BVernon
BVernon

Reputation: 3747

Why won't Ajax.BeginForm replace div?

I'm using jquery popup overlay (http://dev.vast.com/jquery-popup-overlay/) to display the contents of the Credit action (shown below).

With the code shown below, I am expecting the fields in the popup to be cleared since I am returning the partial view with a newly created model with no values set; however the fields are not updated at all.

The crazy thing is, if I comment out the "return PartialView(model);" statement and uncomment the "return Json("Yay it worked!");" then the popup gets replaced with "Yay it worked!". (Yes, I also have to change the return type of the action when I uncomment that line).

Why would Ajax.BeginForm have no problem replacing the target div with the text of a Json return value, but totally ignore the results of a PartialViewResult?

public PartialViewResult Credit()
{
    CreditPaymentModel model = new CreditPaymentModel();
    return PartialView(model);
}

[HttpPost, ValidateAntiForgeryToken]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public PartialViewResult Credit(CreditPaymentModel model) {

    model = new CreditPaymentModel(); // breakpoint here
    return PartialView(model);
    //return Json("Yay it worked!");
}

EDIT: I just added a function to process the OnSuccess event. I can step through the view as it's being processed (after submitting and it returns the view with an empty model) and verify that the values are in fact null, however when it gets to the OnSuccess method the data it receives shows the original data that was submitted rather than the blank values I'm expecting. Normally I would expect this to be due to caching, but I have an OutputCache attribute over the Credit action and I have set the AllowCache property to false in the AjaxOptions so I don't understand how this could be happening?!

Upvotes: 0

Views: 204

Answers (1)

user3559349
user3559349

Reputation:

The HtmlHelper methods your using in your partial view form use values from ModelState rather than from your model if they exist, which in your case they do because your POST method has a parameter which is typeof CreditPaymentModel and each value of CreditPaymentModel has been added to ModelState by the DefaultModelBinder.

You would need to use ModelState.Clear; before you return the model if you want to display the default values for CreditPaymentModel. For a more detailed explanation of the behavior, refer TextBoxFor displaying initial value, not the value updated from code.

Note however, because your returning a new partial, all client side validation will be lost unless you re-parse the $.validator (refer this answer for an example). All this will be easier is you use the $.ajax() method which gives far more flexibility, and in your case, have the method returns the partial is ModelState is invalid and you want to display validation errors, or return null otherwise. In the ajax success callback, if the result is null, just reset the existing form controls, otherwise replace the partial and re-parse the $.validator.

Upvotes: 1

Related Questions