I am using an MVC 3 Ajax.BeginForm call for form submission with client side validation. One of the input fields is a postcode (postalcode) and as well as validating the format I also want to check to see if it exists in a database table of approximatley 2 million entries.
The solution I chose was to use the an BeginForm OnBegin call to perform a lookup before submission and if the postcode does not exist offer the user the options of accepting it or re-entering. I am performing the postcode lookup using another Ajax call
The problem is that I need to wait for the the inner Ajax call to return and process the response before returning to the outer call but as this is an asynchronous call the function is continusing before the inner Ajax has completed.
I can see several non-preferred solutions, e.g. making the inner Ajax call synchronous or catching the submit button click event but does anyone have suggestions for a clean unobtrusive solution.
Thank you.
You could use the [Remote] attribute to perform remote validation. You simply decorate the corresponding property on your view model with this attribute and then specify the controller action that will perform the actual validation.
Obviously no matter which solution you choose you absolutely must perform the same check once the form is submitted on the server because by the time you initially checked with AJAX and the time the form is actually submitted your database data could change and what was valid initially be no longer valid.
Related
I'm using ASP.net MVC5 and I have just created a simple search form. Upon submitting, the controller is called with GET parameters.
The thing is that all parameters are sent regardless if the user has filled it resulting in an ugly & bigger URL that is needed.
So, what needs to be done in order that the form won't send null/empty fields?
I have an asp.mvc app the presents to the user different forms when they click on the next button - like a wizard. I do it this way so I can use JQuery to validate each form as the user progresses through them. i.e.
...
// use jquery validator to funk up the form validation
// user clicks the Next button ...
switch(currPageIndex) {
case 0:
if($('#form1'.valid()) {
$('#form1').hide();
$('#form2').show();
}
break;
}
...
However I can't use a single submit button to post the all the forms formcollection data back to my controller - if I do I only get back the one form that the submit button was in and not all of them.
Is there some magic icantation I can type in to get all the forms data sent back to the controller?
Presumably I can cruft up the data myself and send it back to my controller as a jason string, but I'm not sure if this is the best way.
Many thanks.
Wizard-like forms basically rely on a model which is kept on the server-side (in session or a database table) and kept updated.
For example, each post from the client you get back the model from session or database and then call UpdateModel() using the FormCollection which updates the model and the you can check if it is valid.
You can only submit one form at a time, however there are multiple ways around this in your scenario. When you change to the second form you could populate some hidden fields using javascript that would contain the information from the previous form. Then it would all be in the second form and you wouldn't have a problem getting the information.
You could also do it via ajax/json, but then you would probably want to do it with both of the forms data anyway.
In the end I just json'd up the form data and ajax'd it over to the controller, it works very well, nice and and clean to.
many thanks for the replies.
You can do that using $('#form1').submit() function, I don't think there is another way.
I have something like this:
I am using Ajax.BeginForm and its updatetargetid is a div which basically informs user whether it was successfully submitted or not and the problem, if any.
My controller function that is handling the form submission checks if there were any errors like duplicate entries and such and does re-checking of client-side rules and returns Content(....) accordingly.
This is what I'm using to clear form afterwards, but as you can see that the form would still get cleared even when my controller function has detected some problem that client-side didn't. I set AjaxOptions OnComplete = "onComplete".
function onComplete() {
if ($("#myForm").validate().form()) {
$("#myForm").clearForm();
}
}
Use function onComplete(ajaxContext){ } instead of function onComplete() {}
From the server end, if there are model validation errors, it usually means the validation summary (if supported) contains some error messages. Using ajaxContext, you can read the the response that is returned as part of ajax call and check the values of validation summary element.
Other option is to design a strategy between your controller and view - e.g. specify an error indicator as part of your response header and use this to decide whether to clear your form or not in OnComplete handler.
so then whats the problem? You simply dont call the onComplete function when there is a server side error. But instead display an error message to let the user know that nothing will happen as there was a server side error. And this way the form will not get cleared.
If everything does work on the server side, then only then will you call the onComplete function.
PK
Perhaps this is impossible, but I figured I would ask anyway. I'm working on an ASP.NET MVC application that uses jquery/AJAX extensively. One of the AJAX tasks that gets performed is a call to controller action that returns a URL to redirect the user to.
What I would like to do is to have the same controller context when making an AJAX call as I do on the current page. The reason for this is because the controller action called by AJAX makes use of the Url.Action() method and I need it to use the same route values as what is currently being used on the current page.
So for example, if a user is currently on: /Site/Search/Advanced/Widgets/Black and Blue/1/Descending, mapping to a route of Site/Search/Advanced/{objectType}/{query}/{pageNum}/{displayMethod}, with {objectType} defaulting to "Cars" (not "Widgets").
I would like a call to Url.Action("Advanced", "Search", new {query="Something else"}) to generate /Site/Search/Advanced/Widgets/Something else/1/Descending.
As it stands, the call will generate /Site/Search/Advanced/Cars/Something else, because the controller does not what context it is in.
My alternative is to specify the additional parameters directly in the Url.Action call, but that would require a lot more complexity with values coming in and out of jquery AJAX through various hidden fields, which would be a huge mess...
Any ideas?
Assuming that you on every ajax call want the route values you haven't specified to be the same as in the original non-ajax request, you could always make use of ViewContext.RouteData to add the extra parameters to the ajax call. When the ajax call is returned, you use the route data to add to any new links in the asynchronously loaded results.
Another way is to use the Session object to keep track of the last request, and change the values if new ones are sent.
On the other hand, I would like to question your goal (if this search scenario is your actual scenario): If I search for something, browse to page 4, and then enter a new search term, I don't expect to go to page 4 of the new search results - I expect the first page (although I do expect that my chosen sorting order is preserved...).
In my MVC application for booking accommodation I have the following:
Action to display the selected room with input-forms for extra info GET:"Details"
This view has multiple forms on it, each posting to a different action.
Examples:
Action to update the number of guests POST:"UpdateGuests"
Action to select start date POST:"SelectStartDate"
Action to add breakfast POST:"AddBreakfast"
Action to delete room POST:"RemoveProductFromCart"
Action to proceed to next step POST:"Proceed"
Most of these actions will redirect back to the GET:"Details" view so the user can perform another action if required, in the case of the proceed, this will redirect to the next view OR if there is some reason they cannot proceed it will display the validation message as to why on the "Details" view.
I'm not sure of the best way to deal with validation, here's some options I've thought of.
use TempData[] to store validation messages and REDIRECT to "Details" view where we add any TempData errors so the ModelState.
in the POST:"xxxxxx" Action populate the ModelState and RENDER the "Details"
This is not a high volume site so TempData is an option.
Any ideas gratefully welcomed.
Edit:
Additional info:
I'm using DataAnnotations for validation rules in some places.
adding Ajax as progressive enhancement is planned, but it should work without.
I think that your second option is the best : each post actions will do the required validations, populate the ModelState with the error messages and every post will return the same view, rebuilt using your model.
Another option, a little bit harder but giving a much better user experience is to do some actions (like update number of people, select start date, add breakfast) using an ajax call. That way, you can return only the little bit of informations required by this action, refresh only that part of the screen and add some error messages if needed.
I hope it will help.
Have you taken a look at how nerd Dinner does validation? I've used this approach with forms that contain several Partial Views and it works great.
You can even modify to validate using jQuery on the fly if that's what you want to do.