Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC: Can you use Data Annotations / Validation with an AJAX / jQuery call?

Can you use Data Annotations / Validation with an AJAX / jQuery call? If so, please provide an example or a post which shows an example.

Basically I have seen an example of how to use Data Annotations, however it was with a full post back. Is there a way to do with an AJAX / jQuery call? Not sure how you would do this since I am not sure how you would construct the Model object on the client side. (I assume this is what you would have to do.)

Someone told me this can be done, but I just don't understand how it can be.

Thanks for your help.

like image 880
Richard Avatar asked Feb 24 '23 09:02

Richard


2 Answers

Yes - 100% I do it all the time. Use Ajax.BeginForm and use unobtrusive validation http://completedevelopment.blogspot.com/2011/02/unobstrusive-javascript-in-mvc-3-helps.html

this will emit everything you need client side.. although you have to hook up the validators again to tell jQuery that we have loaded some content that it will need to validate

I believe I got this idea/code from: http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/

either way what I have below works and I'm currently using it although I added a little debugging to it.

(function ($) {
    $.validator.unobtrusive.parseDynamicContent = function (selector) {

        var len = $(selector).length;

        //alert('got length');
        if ($(selector).length == 0) {
            alert('The selector (usually a div) passed in as the root level to start validation parsing at (rather than parsing the whole document again) could not be found in the DOM. Validation on this form will not likely continue. The selector parameter is:' + selector);
            return;
        }
        //use the normal unobstrusive.parse method
        $.validator.unobtrusive.parse(selector);

        //get the relevant form
        var form = $(selector).first().closest('form');
        if (form.length == 0) {
            alert('Could not find a form that was a parent of selector:' + selector + '\nValidation may not work properly');
            return;
        }


        //get the collections of unobstrusive validators, and jquery validators
        //and compare the two
        var unobtrusiveValidation = form.data('unobtrusiveValidation');
        //alert(unobtrusiveValidation.length);
        var validator = form.validate();

        $.each(unobtrusiveValidation.options.rules, function (elname, elrules) {
            if (validator.settings.rules[elname] == undefined) {
                var args = {};
                $.extend(args, elrules);
                args.messages = unobtrusiveValidation.options.messages[elname];
                //$('[name=' + elname + ']').rules("add", args);
                $('[name="' + elname + '"]').rules("add", args);
            } else {
                $.each(elrules, function (rulename, data) {
                    if (validator.settings.rules[elname][rulename] == undefined) {
                        var args = {};
                        args[rulename] = data;
                        args.messages = unobtrusiveValidation.options.messages[elname][rulename];

                        $('[name="' + elname + '"]').rules("add", args);
                    }
                });
            }
        });

    }
})($);

then in each partial view (or page) that you use ajax to load, have this: (note editCustomerAddress is the div name that contains my new content, so jQuery doesnt have to reparse everything on my page but only from my dynamic content down)

  <script type="text/javascript">
        try {
            //Since this may have been loaded as dynamic content ensure jQuery client validation knows we should be validating the content in this view.
            //jQuery validation runs when the original page loads - on the original content and not on dynamic (in this case ajax) content.
            //We don't need to validate the whole form again, only from this div down.

            //if I have a problem in jQuery 5, then try: $.validator.unobtrusive.parse("#editZone > div > form"); 
            $.validator.unobtrusive.parseDynamicContent('#editCustomerAddress');
        }
        catch (err) {
            alert('An error occured trying to tell jQuery to validate our new content. Ensure the code for parseDynamicContent has been included and you are referencing a valid element. Also, ensure the form has a context if it is a partial view by calling if (ViewContext.FormContext == null){ViewContext.FormContext = new FormContext();}  If that code is not present, data-val-* attributes will not be rendered.\n' + err);
        }

    </script>

Also - you want to make sure your partial views that don't have their own ajax or html forms you need to have a form context via

@{ if(ViewContext.FormContext == null) {ViewContext.FormContext = new FormContext(); }

otherwise your data-val-* attributes will not be emitted by the helper methods. You need this if your views do not have an Ajax.BeginForm or Html.BeginForm to create their own form context.

like image 135
Adam Tuliper Avatar answered Mar 08 '23 23:03

Adam Tuliper


If you use Html.AjaxForm (instead of Html.BeginForm) then it will validate using Ajax.

However I don't think you can validate using jQuery. Microsoft has it's own Ajax libraries and they call/maintain it themselves. I don't think you can hook your own code in between.

like image 30
neebz Avatar answered Mar 08 '23 23:03

neebz