Prevent updating html with some conditions in MVC Ajax.BeginForm? - c#

I have the following code in my View,
It's for searching in a site, a user can submit the following form multiple times.
#using (Ajax.BeginRouteForm("Search", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "SearchContents",
LoadingElementId = "SearchAjaxLoader",
OnSuccess = "SearchLoadContentsOnSuccess",
OnFailure = "SearchLoadContentsOnFailure",
OnBegin = "SearchLoadContentsOnBegin",
OnComplete = "SearchLoadContentsOnComplete",
}))
{
#Html.AntiForgeryToken()
<input type="text" name="Search" />
<input type="submit" value="Submit" />
}
I wanna reject old ajax results and show the latest ajax result only.
In a non mvc Ajax form, I was creating an array as ajax counter and compare the server responses with it to prevent update html.
I wanna know how I can prevent Ajax.BeginForm to update Html on some conditions.

As an example I will demonstrate with an OnSuccess call, you can do this for each event you wish to handle.
In your AjaxOptions remove this to prevent the replace;
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "SearchContents",
In you SearchLoadContentsOnSuccess JavaScript method, without seeing the method I am guesing it will be something like this:
function SearchLoadContentsOnSuccess()
{
// Do something
}
Change it to this:
function SearchLoadContentsOnSuccess(e)
{
// Do something
}
Now the e parameter will contain the data that is sent back from your ajax call.
In your updated method, I would simply check the response and act acordingly.
As an example if you response contains a value and results property:
function SearchLoadContentsOnSuccess(e)
{
// Do something
$(e.value == 1)
{
$('#SearchContents').html(e.results);
}
}
You would simply change the javascript in the above method to suite your needs.

Related

Ajax begin form not picking up strong type drop down list value

I am using Ajax begin form for a search page to bring back results. I have the following markup.
#using (Ajax.BeginForm("GetSearchResults",
"MYController",
new
{
siteID = Model.SiteID
},
new AjaxOptions()
{
HttpMethod = "GET",
AllowCache = true,
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "search-reults"
}))
{
#Html_DropDownListFor(model => model.SiteID, Model.StatusCollection)
}
There are a few other strong type textboxes and a submit button on the page. All textboxes submit data back to the controller but the drop down list doesn't. It always submits the default value 0. Are there any other steps I need to do to pick up the value or something in the JQuery onchange event?
Removing the route parameter siteID worked. I do not need to pass strong type control values through as route parameters.

Doesn't show view from controller even debugger goes inside View

I am new in MVC .net. I am not able to call view from controller. I have debug the flow. It goes to view successfully but doesn't show view on screen.
Controller name: Downloads
Action name: MakePayment
Redirect view: Success //success is view of View/Downloads/Success.cshtml
Code: DownloadsController
[HttpPost]
public ActionResult MakePayment(Downloads CCM)
{
if (true)
{
return View("Success");
}
else
{
return View("Failure");
}
}
View
#{
ViewBag.Title = "Success";
}
<h2>Your transaction has been completed successfully.</h2>
Method that I use to call the ActionResult MakePayment. I had use Ajax here because I wanted to call javascript function before form get submit.
View: Index.cshtml
#using (Ajax.BeginForm("MakePayment", "Downloads", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, OnBegin = "payByCreditCard" }))
{
//submit button
}
According to the return View("Success");, it should call the view. In fact when I debug the flow, it goes to Success view but doesn't display the view on screen. It keeps old view on screen.
Degug route after success: _ViewStart-->Success.cshtml-->_Layout.cshtml.
Can anybody suggest me if I am missing something?
Since you are making an ajax call using Ajax.BeginForm helper method, you need to specify where the response (of the ajax call) to be replaced in the DOM. You can specify that using the UpdateTargetId property
#using (Ajax.BeginForm("MakePayment", "Downloads", new AjaxOptions { HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId="YourDivToShowResult"
OnBegin = "payByCreditCard" }))
{
<div id="YourDivToShowResult"></div>
<input type="submit" />
}
Since this is an ajax call, It will not do a redirect. Instead,it will update the content of the div (with Id YourDivToShowResult) in the same page with response coming back which is the markup returned by Success view.
Also since we are showing a partial page update, you might consider returning a partial view.
[HttpPost]
public ActionResult MakePayment(Downloads CCM)
{
if (everything is good)
{
return PartialView("Success");
}
else
{
return PartialView("Failure");
}
}
This will return the markup from either of those views without the layout.
If you want to go to other view you have to redirect the page like:
return RedirectToAction("Success", "Downloads");

Display Success message on the same page when submit

I'm using Html.Beginform in view page and get the parameters using FormCollection to the controller i want to return the Success message on the same ViewPage as a result.i'm using following code,
public string InsertDetails(FormCollection collection)
{
string result = "Record Inserted Successfully!";
return result;
}
It shows the success message on the new page.How can i resolve this? what i have to return to get the Success message on the same page?
Personally, I'd pop the result string into the ViewBag.
public ActionResult InsertDetails(FormCollection collection)
{
//DO LOGIC TO INSERT DETAILS
ViewBag.result = "Record Inserted Successfully!";
return View();
}
Then on the web page:
<p>#ViewBag.result</p>
I have following Options.
1. Use Ajax Begin Form with AjaxOptions like below
#using (Ajax.BeginForm("ActionName", "ControllerName", new { area = "AreaName" }, new
AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "alert('Success');" //This will execute once the Ajax call is finished.
}, null))
{
<input type="submit" name="nameSubmit" value="Submit" />
}
2. Use JQuery to Manually Setup the XHR Request
$.ajax({
url: "#Url.Action("ActionName", "ControllerName", new { area = "AreaName" });",
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({param : Value})
})
.done(function () { alert('Success');}) //This will execute when you request is completed.
.fail(function () { })
My Suggestions
There are following disadvantages while using the FormCollection
Point - 1
In case FormCollection is being used...It will be mandatory to Type Cast the Primitive Type Values un-necessarily because while getting the entry of specific Index of the System.Collections.Specialized.NameValueCollection, value being returned is of type String. This situation will not come in case of Strongly Typed View-Models.
Issue - 2
When you submit the form and goes to Post Action Method, and View-Model as Parameter exists in the Action method, you have the provision to send back the Posted Values to you View. Otherwise, write the code again to send back via TempData/ViewData/ViewBag
Point - 3
We have Data Annotations that can be implemented in View Model or Custom Validations.
ASP.Net MVC simplifies model validatons using Data Annotation. Data Annotations are attributes thyat are applied over properties. We can create custom validation Attribute by inheriting the built-in Validation Attribute class.
Point - 4
Example you have the following HTML
<input type="text" name="textBox1" value="harsha" customAttr1 = "MyValue" />
Question : How can we access the value of customAttr1 from the above eg from inside the controller
Answer : When a form get posted only the name and value of elements are posted back to the server. You can also use Hidden Fields to post the Attributes to Post Action method.
Alternatives : Use a bit of jQuery to get the custom attribute values, and post that along with the form values to action method
Another option is to rather put what you got in your custom attributes in hidden controls
That's the reason, I would always prefer to use View-Models
we can do it on Form inside view
#using (Ajax.BeginForm("Action", "Controller", new AjaxOptions { HttpMethod = "POST", OnSuccess = "Showmessage" }))
[HttpPost]
public ActionResult Test(TestViewModel model)
{
return Json(new {isok=true, message="Your Message" });
}
function Showmessage(data)
{
$('#Element').html('Successfully Submitted');
}

ASP.Net MVC Ajax.BeginForm OnComplete pass c# arguments in Razor view

I have the following code in a MVC c# Razor view:
#{string url = "/Projects/_MonthRangesScriptsPartial";}
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = "updategraphArrayScript(#url,#ViewBag.InputResourceID)"
}))
The code works almost perfectly, but I would like to resolve the c# variables to their values in the OnComplete line.
That is to say, the Razor engin should resolve the code to (for example):
<form action="/Projects/_MonthRanges/55"
data-ajax="true" data-ajax-complete="updategraphArrayScript(/Projects/assets,55)"
...>
Rather than:
<form action="/Projects/_MonthRanges/55"
data-ajax="true" data-ajax-complete="updategraphArrayScript(#url,#ViewBag.InputResourceID)"
...>
Simply create another variable string:
#{
string url = "/Projects/_MonthRangesScriptsPartial";
string onComplete = String.Format("updategraphArrayScript({0}, {1})", url, ViewBag.InputResourceID);
}
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = #onComplete
}))
Take off the # when you assign your OnComplete value. You don't need it since you're already in the context of server side code.
# is used to switch html rendering context to server side code, and <text></text> is used to switch from server side context to html rendering. In example given above, you're already in the server side code context of the BeginForm() method so the # is not needed. You're not writing the value of onComplete to the page, BeginForm() will handle all that.

Get query string from an ajax call

Hi I am trying to get a querystring from an ajax call and it does not seem to work so well.Here is my code:
#Ajax.ActionLink("Add To Cart" ,
"AddToCart" ,
"Products",
new {
ProductId = #products.ElementAt(0).Value
},
new AjaxOptions{
Url = "/Products/AddToCart",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "UpdateCart",
HttpMethod = "GET"
})
Each link I have in my application calls something like this:
Products/AddToCart?ProductId=5
This is the controller it calls:
public ActionResult AddToCart(string ProductId)
{
string ProductCeva = ProductId;
}
Now from what I learned so far about MVC3 I assumed that the parameter ProductId would be 5 in our case , but when I debug the code , I get that it is null.
What am I doing wrong here and how can I get the ProductId query string in this casE?
Remove the Url = "/Products/AddToCart", bit from your AjaxOptions.
Why?
Here's why. The following code:
#Ajax.ActionLink(
"Add To Cart" ,
"AddToCart" ,
"Products",
new {
ProductId = #products.ElementAt(0).Value
},
new AjaxOptions {
Url = "/Products/AddToCart",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "UpdateCart",
HttpMethod = "GET"
}
)
generates:
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#UpdateCart" data-ajax-url="/Products/AddToCart" href="/Products/AddToCart?ProductId=5">Add To Cart</a>
Now even if the href of the generated anchor is correct (/Products/AddToCart?ProductId=5) that's not what is used for the AJAX request. The jquery.unobtrusive-ajax.js that you are using and which unobtrusively AJAXifies all anchors uses the data-ajax-url attribute (if present) when sending the AJAX request instead of the href attribute. Now look at the value of the data-ajax-url attribute and you will understand why you get null in your controller action.
You would also have seen this if you had used FireBug or a similar javascript debugging tool because when you would have inspected the Network tab to see why your AJAX request is not working you would have seen the wrong url being used.
Long story short two things to remember from this question (the first being more important as it allows you to deduce the second):
Use FireBug
the Url property of the AjaxOptions allows you to override the url to be used when sending the AJAX request.

Categories

Resources