The parameter is not passed from the view to the action - ajax

Here is the dropdownlist which contains the parameter (selected value) that I would like to pass to the view:
<select id="sltBiblioSite" name="sltBiblioSite">
<option>Sélectionnez un BiblioSite</option>
#*Iterating BiblioSite Model*#
#foreach (var item in Model)
{
<option>
#item.NomSite
</option>
}
</select>
Here is where I tried different things (see commented code below) to pass the parameter to the fucntion:
var selectedBiblioSiteName;
$("#sltBiblioSite").change(function () {
//selectedBiblioSiteName = $("#sltBiblioSite").val();
//selectedBiblioSiteName = $("#sltBiblioSite").val().trim();
//selectedBiblioSiteName = $("#sltBiblioSite option:selected").text();
//selectedBiblioSiteName = $("#sltBiblioSite > option:selected").attr("value")
...
}
});
and here is one of the functions who is supposed to pass the parameter by calling the partial view.
function getReservationTable() {
$.ajax({
// Get Reservation PartialView
url: "/Home/ReservationsToPartialView",
type: 'Get',
data: { biblioSiteName: selectedBiblioSiteName },
success: function (data) {
$("#reservationDetailTable").empty().append(data);
},
error: function () {
alert("something seems wrong");
}
});
}
I tried to hardcode the parameter in the action and it's working.
The problem seems to be in the view but I don't know where, please help me to fix this problem.
public ActionResult ReservationsToPartialView(string biblioSiteNom)
{
//biblioSiteNom = "La feuille de chene";
var reservationByBiblio = ReservationLinq.GetReservationByBiblioSite(biblioSiteNom);
return PartialView("ReservationPV", reservationByBiblio);
}

I haven't done this in a long time, so I might be completely wrong but I think you are passing wrong parameter name. In your ajax request you have biblioSiteName and in your actions its biblioSiteNom.
Also try some alert before calling the ajax to see whether the read parameter biblioSiteName is correct.

Related

Asp.NET MCV how to call a viewmodel function that performs a db connection on button click correctly?

I have a few viewmodels, which contains a few functions like:
public override string ToString()
{
return $"{M_IV_ID} {M_IV_INVOICEAMOUNT} {M_IV_MANDANT} {M_IV_TOTALAMOUNT} {M_IV_VEHICLE_PURCHASE} {M_IV_URGENT}";
}
And update / insert functionalities. All of them work. I wrote them separately from my Asp.NET project and tested them since I wanted to do my back end first.
Now I tried to use those functions in my Asp.NET application:
First I get Data from the db in my Controller:
M_IV_INVOICE invoice = QueryBuilder.GetFirstOrDefault(new M_IV_INVOICE(), #"WHERE M_IV_ID IN (75693)");
And pass it to my view:
public ActionResult Index()
{
return View(invoice);
}
Now I tried to use my toString() method just to see if it works:
<form id="formUpdate" runat="server">
<div>
<asp:button id="Button" class="btn btn-primary" runat="server">Update</asp:button>
</div>
</form>
#{
string MyFunction()
{
return Model.ToString();
}
}
#section Scripts
{
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
var button = document.getElementById('Button');
button.addEventListener('click', function () {
var test = "#MyFunction()";
console.log(test);
});
});
</script>
}
And if I do this, it works, and I get my model values printed in the browser console.
If I try to use my Update function instead of the toString() method:
public bool Update()
{
using (IDbConnection conn = ConnectionManager.GetConnection())
{
try
{
conn.Query(QueryBuilder.BuildUpdateForEntity(this, string.Format(" WHERE {0} = {1}", GetKey().Item1, GetKey().Item2)));
return true;
}catch(Exception e)
{
// TODO: Exceptionhandling
}
}
return false;
}
I get a Ora Exception right when the page loads, no button click performed:
Oracle.DataAccess.Client.OracleException: ORA-00936: missing expression
I struggle with understanding why, though.
The select I perform in my controller to get the data in the first place is working just fine, and as I said, if I print my model on button click, it works too.
What am I missing?
Edit:
It seems like the function is directly called while the eventhandler is added and since it has no data at the time, the ORA error is occurring.
But why? I don't understand this behavior.
Another Edit:
It has indeed something to do with the model isn't ready or something:
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function () {
var button = document.getElementById('Button');
button.addEventListener('click', function () {
setTimeout(() => { console.log("#MyFunction()") }, 3000);
});
});
</script>
I added the delay and no error on loading the page.
But that would be just a band aid, not a solution.
If someone has an idea how to prevent that behavior, I would appreciate it.
The #{}symbol is used to write server-side C# or VB code with HTML code, so in the javascript, when you use the #MyFunction() function, the Myfunction will execute. You could set a break point in the MyFunction and the button click event to check it, no matter using the ToString() method or the Update() method, they will work when the DOMContent Loaded. So, when use the Update() method, you will meet the missing expression error.
Based on your description, you want to do some action (call the server-side function/method) when user clicks the button, right? If that is the case, I suggest in the controller you can add the Myfunction and Update action methods, then, in the button click event, you can use JQuery get(), post() or Ajax method to call the action method, refer the following code:
Controller:
[HttpPost]
public JsonResult AjaxMethod(string name)
{
PersonModel person = new PersonModel
{
Name = name,
DateTime = DateTime.Now.ToString()
};
return Json(person);
}
and View Page:
<input type="text" id="txtName" />
<input type="button" id="btnGet" value="Get Current Time" />
#section Scripts{
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
$(function () {
$("#btnGet").click(function () {
$.ajax({
type: "POST",
url: "/Test/AjaxMethod",
data: { name: $("#txtName").val() },
success: function (response) {
alert("Hello: " + response.name + " .\nCurrent Date and Time: " + response.dateTime);
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
});
</script>
}

on check box check send value to partial view and update it mvc 3

i have two partial view one is having a 5 checkbox (for filtering) and another will display the filtered data.
<input type="checkbox" data-toggle="checkbox" id="2000-5000"/>Rs.2000-Rs.5000
<input type="checkbox" data-toggle="checkbox" id="2000-5000"/>Rs.2000-Rs.5000
and with help of jquery am sending the request to controller..
public PartialViewResult PhonesPartail(int? id,string where)
{
var list = paginateRsult(id, "", where).ToList();
ViewData["totalpages"] = totalPages;
return PartialView("_phonelist",list);
}
and the jquery
$(document).on("change", ".price-checkbox input[type=checkbox]", function () {
if ($(this).is(":checked")) {
var prange = $(this).attr("id");
var parray = prange.split('-');
var whereclause = "price>=" + parray[0] + " and price <=" + parray[1];
$.ajax({
url: '../../Phones/PhonesPartail',
data: { where: whereclause },
type: 'POST',
success: function (data) {
$("#phone-list").append(data);
}
});
}
});
now the list which is returned , is getting added to the div with entire html page.. means again the html page is getting added in the div..
any solution..
Thanks in advance...
use html() function of jquery
It will paste data returned by partial view in to a div rather then appending it to div
$("#phone-list").html(data);

Calling multiple action methods (using ajax) and showing the result of last in a new tab

I have a form in which I need to call two action methods, one after the other. This is how the flow goes.
First I check if the prerequisite data is entered by the user. If not then I show a message that user needs to enter the data first.
If all the prerequisite data is entered, I call an action method which return data. If there is no data returned then I show a message "No data found" on the same page.
If data is returned then I call another action method present in a different controller, which returns a view with all the data, in a new tab.
The View:
#using (Ajax.BeginForm("Index", "OrderListItems", null, new AjaxOptions { OnBegin = "verifyRequiredData"}, new { #id = "formCreateOrderListReport", #target = "_blank" }))
{
//Contains controls and a button
}
The Script in this View:
function verifyRequiredData() {
if ($("#dtScheduledDate").val() == "") {
$('#dvValidationSummary').html("");
var errorMessage = "";
errorMessage = "<span>Please correct the following errors:</span><ul>";
errorMessage += "<li>Please enter Scheduled date</li>";
$('#dvValidationSummary').append(errorMessage);
$('#dvValidationSummary').removeClass('validation-summary-valid').addClass('validation-summary-errors');
return false;
}
else {
$('#dvValidationSummary').addClass('validation-summary-valid').removeClass('validation-summary-errors');
$('#dvValidationSummary').html("");
$.ajax({
type: "GET",
url: '#Url.Action("GetOrderListReport", "OrderList")',
data: {
ScheduledDate: $("#dtScheduledDate").val(),
Crews: $('#selAddCrewMembers').val(),
Priorities: $('#selPriority').val(),
ServiceTypes: $('#selServiceTypes').val(),
IsMeterInfoRequired: $('#chkPrintMeterInfo').val()
},
cache: false,
success: function (data) {
debugger;
if (data !== "No data found") {
//var newUrl = '#Url.Action("Index", "OrderListItems")';
//window.open(newUrl, '_blank');
return true;
} else {
//Show message "No data found"
return false;
}
}
});
return false;
}
}
The "GetOrderListReport" Action method in "OrderList" Controller:
public ActionResult GetOrderListReport(OrderListModel model)
{
var contract = new OrderReportDrilldownParamDataContract
{
ScheduledDate = model.ScheduledDate
//Setting other properties as well
};
var result = OrderDataModel.GetOrderList(contract);
if (string.IsNullOrWhiteSpace(result) || string.IsNullOrEmpty(result))
{
return Json("No data found", JsonRequestBehavior.AllowGet);
}
var deserializedData = SO.Core.ExtensionMethods.DeserializeObjectFromJson<OrderReportDrilldownDataContract>(result);
// send it to index method for list
TempData["DataContract"] = deserializedData;
return Json(deserializedData, JsonRequestBehavior.AllowGet);
}
The last action method present in OrderListItems Controller, the result of which needs to be shown in a new tab:
public ActionResult Index()
{
var deserializedData = TempData["DataContract"] as OrderReportDrilldownDataContract;
var model = new OrderListItemViewModel(deserializedData);
return View(model);
}
The problem is that I am not seeing this data in a new tab, although I have used #target = "_blank" in the Ajax.BeginForm. I have also tried to use window.open(newUrl, '_blank') as can be seen above. But still the result is not shown in a new tab.
Please assist as to where I am going wrong?
If you are using the Ajax.BeginForm you shouldn't also be doing an ajax post, as the unobtrusive ajax library will automatically perform an ajax post when submitting the form.
Also, if you use a view model with data annotation validations and client unobtrusive validations, then there would be no need for you to manually validate the data in the begin ajax callback as the form won't be submitted if any validation errors are found.
The only javascript code you need to add in this scenario is a piece of code for the ajax success callback. That will look as the one you currently have, but you need to take into account that opening in new tabs depends on the browser and user settings. It may even be considered as a pop-up by the browser and blocked, requiring the user intervention to allow them as in IE8. You can give it a try on this fiddle.
So this would be your model:
public class OrderListModel
{
[Required]
public DateTime ScheduledDate { get; set; }
//the other properties of the OrderListModel
}
The form will be posted using unobtrusive Ajax to the GetOrderListReport of the OrderList controller. On the sucess callback you will check for the response and when it is different from "No data found", you will then manually open the OrderListItems page on a new tab.
This would be your view:
#model someNamespace.OrderListModel
<script type="text/javascript">
function ViewOrderListItems(data){
debugger;
if (data !== "No data found") {
var newUrl = '#Url.Action("Index", "OrderListItems")';
//this will work or not depending on browser and user settings.
//passing _newtab may work in Firefox too.
window.open(newUrl, '_blank');
} else {
//Show message "No data found" somewhere in the current page
}
}
</script>
#using (Ajax.BeginForm("GetOrderListReport", "OrderList", null,
new AjaxOptions { OnSucces= "ViewOrderListItems"},
new { #id = "formCreateOrderListReport" }))
{
#Html.ValidationSummary(false)
//input and submit buttons
//for inputs, make sure to use the helpers like #Html.TextBoxFor(), #Html.CheckBoxFor(), etc
//so the unobtrusive validation attributes are added to your input elements.
//You may consider using #Html.ValidationMessageFor() so error messages are displayed next to the inputs instead in the validation summary
//Example:
<div>
#Html.LabelFor(m => m.ScheduledDate)
</div>
<div>
#Html.TextBoxFor(m => m.ScheduledDate, new {id = "dtScheduledDate"})
#Html.ValidationMessageFor(m => m.ScheduledDate)
</div>
<input type="submit" value="Get Report" />
}
With this in place, you should be able to post the data in the initial page using ajax. Then based on the response received you will open another window\tab (as mentioned, depending on browser and user settings this may be opened in a new window or even be blocked) with the second page content (OrderListItems).
Here's a skeleton of what I think you are trying to do. Note that window.open is a popup though and most user will have popups blocked.
<form id="formCreateOrderListReport">
<input type="text" vaule="testing" name="id" id="id"/>
<input type="submit" value="submit" />
</form>
<script type="text/javascript">
$('#formCreateOrderListReport').on('submit', function (event) {
$.ajax({
type: "POST",
url: '/home/test',
data: { id: $('#id').val()},
cache: false
}).done(function () {
debugger;
alert("success");
var newUrl = '/home/contact';
window.open(newUrl, '_blank');
}).fail(function () {
debugger;
alert("error");
});
return false;
});
</script>
Scale down the app to get the UI flow that you want then work with data.

Dynamically load Partial Views

How can i dynamically load a Partial View?
I mean I have this view, lets say ListProducts, there I select some dropdownlists with products, etc, and with the selected values from those I wanna fill a partial view, which would be in a div that was invisible but after onchange() event would become visible and with the data from the specific selected items.
Use jQuery's $.load() with a controller action that returns a partial view.
For example:
HTML
<script type="text/javascript">
$(document).ready(function()
{
$("#yourselect").onchange(function()
{
// Home is your controller, Index is your action name
$("#yourdiv").load("#Url.Action("Index","Home")", { 'id' : '123' },
function (response, status, xhr)
{
if (status == "error")
{
alert("An error occurred while loading the results.");
}
});
});
});
</script>
<div id="yourdiv">
</div>
Controller
public virtual ActionResult Index(string id)
{
var myModel = GetSomeData();
return Partial(myModel);
}
View
#model IEnumerable<YourObjects>
#if (Model == null || Model.Count() == 0)
{
<p>No results found</p>
}
else
{
<ul>
#foreach (YourObjects myobject in Model)
{
<li>#myObject.Name</li>
}
</ul>
}
You can do this by following these steps. In your controller, you return a partial view.
[HttpGet]
public virtual ActionResult LoadPartialViewDynamically()
{
var query = _repository.GetQuery();
return PartialView("_PartialViewName", query);
}
then in the view you have an empty div
<div id="partialgoeshere"></div>
and then load the partial view using jQuery:
function LoadPartialView() {
$.get("#Url.Action(MVC.ControllerName.LoadPartialViewDynamically())", { null }, function (data) {
$("#partialgoeshere").empty();
$("#partialgoeshere").html(data);
});
}
Hope this helps
I believe you can do something like this example, just using the change event on your dropdown instead. It's a simple jQuery call, you can find more on the jQuery website.
$("#dropdown").change(function() {
$("#destination").load("/Products/GetProduct", $(this).val(),
function(result) {
// do what you need to do
});
});
The first parameter is the view you need to call for the details.
The second parameter is the selected value.
The third parameter of the $.load function is the callback function, where you can parse the result and do what you need to do.
If you have a multiple select $(this).val() that will give you an array with the selected options.
If you want only return a Json object you may want to follow this example.
Use Ajax :)
http://api.jquery.com/jQuery.ajax/
Example:
$.post(window.gRootPath + "Customer/PartialView", { Question: questionId})
.done(function (data) {
$('#partialDiv').html(data.responceText);
});
You can use ajax to call action an then just insert html string using jQuery to the page where you want it to appear:
Server-side:
Render partial view to string
Renders partial view on server to html string, useful when you need to add partial view to ASP.NET MVC page via AJAX.
Client-side:
$('#yourDdl').change(function()
{
$.get('/InsertPartialViewUsingAjax', function (data)
{
$('#container').html(data);
});
});
The following article tells you how to do it with minimum javascript. Basically you return html instead of JSON to your response object.
https://www.simple-talk.com/content/article.aspx?article=2118

pass data from view to controller without refreshing the view

i have a script in my view which is:
$('.datepicker').datepicker
(
{ onSelect: function (dateText, inst) {
//pass dateText to my controller
});
</script>
my controller is like this:
public ActionResult Index()
{
string dateSelected = dateText; //read dateText here
if (DateTime.TryParse(dateSelected, out date))
{
date = Convert.ToDateTime(dateSelected);
var reservations = db.Reservations.Where(r => r.Date == date).Include(r => r.Employee).Include(r => r.Room).OrderByDescending(r => r.Date);
return View(reservations);
}
return View();
}
i want dateText to be passed to the controller without the current page being refreshed or reloaded. how to do that?
i tried forms earlier and on the onselect event of the datepicker, i automatically submit the form so the controller can accept it. but i do not want the current page to be refreshed or reloaded.
i just want to pass dateText to the controller without the user noticing the passing.. some sort of $.post i guess but i dont know how to implement it..
UPDATE: here is my try, what is wrong:
ok here is my script:
JSONstring = JSON.stringify(dateText);
$.post("/Home/Index", { jsonData: JSONstring });
here is my controller:
public ActionResult Index(string jsonData)
{
CacheClear();
string dateSelected = jsonData;
.....
//i tried to debug it, but no value of jsonData
}
i want dateText to be passed to the controller without the current
page being refreshed or reloaded. how to do that?
You could use AJAX.
use ajax and send all the variables or data in the ajax data string and provide the url of your controller for example
function add_to_cart(id , title, price,qty){
$.ajax({
type: "POST",
url: "your controller" + id ,
data: "&title=" + title + "&price=" + price +"&quantity=" + qty ,
complete: function(data) {
//alert("Item added to cart");
}
});
}

Resources