Monday, May 30, 2011

MVC3, Client Side Validation, and dynamically loaded forms

Recently, I was charged with creating a user edit screen.  The user edit screen was to have 4 different "areas".

1) User Details
2) Actions (disable.. enable)
3) User Roles
4) Audit

We decided to ajax out all the different sections as to make the website more responsive.  If someone disabled an account, all we would have to do is update sections 1 and section 2.  No need to make an expensive call to try and establish all the roles the user has in the system.

The problem I has was that when I loaded the form using jquery get method, the client side validation would not work.  This made it a pain for getting proper error messages back to the client.  I didn't want to have to parse a result and start using my javascript skillz to display messages all over the place.  In fact, the built-in client side validation "features" that MVC3 provides are quite nice.  You define validator logic in one place and go from there....

In any event, the point is, when you dynamically load a form, the client side validation does not work out of the bat. To answer why, we have to look at the jquery.validate.unobtrusive.js libraries that MS provided for us. 


$(function () {
        $jQval.unobtrusive.parse(document);
    });

Great piece of code.  The problem is, this only runs once... when the original document is loaded (unless you include all of your JS again in the AJAX layout you are using.. but that would be a lot of duplication). 

The solution is quite simple.  All you have to do is add a call to the parsing mechanism with the jquery selector for the form you wish to validate.

$.get(
                '@Url.Action("GetPersonalData")',
                {
                    Id: currentUserId
                },
                function (data) {
                    $("#personal").html(data);
                    $.validator.unobtrusive.parse("#personal form:first");
                    ... continue ...

Voila, you will now have client side validation on your dynamically loaded form.

Update:
If you want this form to submit via an ajax post (using jquery natively) you have to determine if the form is valid first.  You can find out more here.


References:
http://stackoverflow.com/questions/4406291/jquery-validate-unobtrusive-not-working-with-dynamic-injected-elements
http://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html