aspnet / jquery-validation-unobtrusive

Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.
MIT License
257 stars 113 forks source link

how to use this plugin with ajax ? #126

Closed John0King closed 2 years ago

John0King commented 4 years ago

I want to submit using ajax , and this code I tried:

$(function () {
            $("#mainForm").validate({
                submitHandler: function (form, e) {
                    var f = $(form);
                    e.preventDefault();
                    console.log('xxxx');
                    $.ajax(f.prop("action"), {
                        type: f.prop("method").toUpperCase(),
                        data: f.serialize()
                    })
                        .then(function (r) {
                            if (r.successed) {
                                alert("Success");
                            }
                            else {
                                alert(r.error);
                            }
                        })
                        .fail(function (e) {
                            alert("Failed");
                        })
                }
            })
        })

but the form will submit without this code

fredericDelaporte commented 3 years ago

I had the same trouble. "Unobtrusive" attaches its own validator, and you cannot set most of its options.

You may follow this StackOverflow answer suggestions.

Instead I solved it by hacking through jQuery validate default options. If you have only one form to validate on the page, you can define your submit handler globally:

$.validator.setDefaults({
    submitHandler: function (form, e) {
        // your code
    }
});

It has to be defined before the unobtrusive initialization, which occurs on ready. Or you will have to re-parse the form with $.validator.unobtrusive.parse(selectorOfYourForm).

In my case, having many forms with different needs, I have used something like this:

let submitHandlers = [];

$.validator.setDefaults({
    submitHandler: function (form, e) {
        let result = true;
        $.each(submitHandlers, function (i, submitHandler) {
            result = submitHandler(form, e) && result;
        });
        return result;
    }
});

function addUnobstrusiveValidationSubmitHandler(submitHandler) {
    if (typeof submitHandler !== 'function') {
        throw 'submitHandler must be a function';
    }
    submitHandlers.push(submitHandler);
}

I leave to each submitHandler the responsibility of working only on forms it has to handle. The submit handler should check the form, and just return true; without doing anything else if it is not a form it should handle. So adding a bad submitHandler acting on unexpected forms will mess other forms or the whole page.

It would be better if we could define the submitHandler in the parse call instead, but currently this call does not take an options object.

There is also some options which can be defined globally by assigning an object to $validator.unobtrusive.options, but I do not find much documentation about this beyond errorClass and errorElement options, and it does not seem to have an option for specifying a submitHandler. As far as I can see from the source, we could only define the following additional options, matching the jQuery validate ones: errorPlacement, invalidHandler and success.

PatrickMcDonald commented 2 years ago

The submitHandler may be a red-herring here. I think you can achieve the same result using plain jQuery:

$("#mainForm").submit(function (e) {
    var f = $(this);
    e.preventDefault(); // or return false after the ajax call
    console.log('xxxx');
    $.ajax(f.prop("action"), {
        type: f.prop("method").toUpperCase(),
        data: f.serialize()
    })
        .then(function (r) {
            if (r.successed) {
                alert("Success");
            } else {
                alert(r.error);
            }
        })
        .fail(function (e) {
            alert("Failed");
        });
});