Как добавить функцию submitHandler при использовании ненавязчивой проверки jQuery? - PullRequest
40 голосов
/ 20 января 2011

Я проверяю форму, используя новые ненавязчивые функции проверки в ASP.NET MVC 3.

Так что нет никакого кода, который я написал для настройки jQuery validate, чтобы начать проверку моей формы.Все это делается путем загрузки библиотеки jQuery.validate.unobtrusive.js.

К сожалению, мне нужно нажать «Вы уверены?»окно сообщения, когда форма действительна, но перед отправкой.С помощью jQuery validate вы добавите опцию handleSubmit при инициализации следующим образом:

$("#my_form").validate({
  rules: {
    field1: "required",
    field1: {email: true },
    field2: "required"
  },
  submitHandler: function(form) {
     if(confirm('Are you sure?')) {
       form.submit();
     }
  }
});

Но вам не нужно инициализировать при использовании ненавязчивой библиотеки.

Любые идеи, где и как я могудобавить обработчик отправки в этом случае?

Thx

Ответы [ 5 ]

65 голосов
/ 22 января 2011

Ненавязчивая библиотека присоединит валидатор ко всем формам, поэтому вы должны заменить submitHandler следующим образом:

$("form").data("validator").settings.submitHandler = function (form) { alert('submit'); form.submit(); };
61 голосов
/ 26 января 2011

Я нашел этот вопрос, когда искал способ установить invalidHandler, а не submitHandler. Интересно, что вы не можете установить invalidHandler таким же образом при использовании ненавязчивой проверки.

Функция не запускается при обнаружении неверной формы:

$("form").data("validator").settings.invalidHandler = function (form, validator) {
    alert('invalid!');
};

Этот подход работает:

$("form").bind("invalid-form.validate", function () {
  alert('invalid!');
});

Похоже, это связано с тем, что скрипт jquery.validate.unobtrusive.js инициализирует плагин Validate , а также с тем, что плагин вызывает обработчик. *

33 голосов
/ 24 декабря 2012

Следующие выводы могут быть интересны, чтобы понять разницу между:

submitHandler : вызывается при успешной проверке формы - прямо перед отправкой на сервер
invalidHandler : вызывается, если проверка не пройдена и сообщения не возвращаются

@ Решение DGreen определенно является наилучшим способом внедрения специальной обработки, если проверка формы не удалась и вам нужно что-то сделать, например, отобразить всплывающую сводку проверки ( invalidHandler )

$("form").bind("invalid-form.validate", function () {
  alert('invalid!');
});

@ Решение PeteHaus - лучший способ сделать что-то, если вы хотите предотвратить обратную передачу успешно проверенной формы ( submitHandler )

$("form").data("validator").settings.submitHandler = function (form) { 
                                                     alert('submit'); form.submit(); };

Однако меня немного беспокоило, какое поведение я переопределял (или не переопределял), привязываясь к методу .validate, как этот, - и почему мне приходилось делать каждый путь по-разному. Поэтому я проверил источник. Я настоятельно рекомендую всем, кто хочет разобраться в этой процедуре, сделать то же самое - добавить несколько «предупреждений» или «отладчиков», и за ним довольно легко следовать *

В любом случае получается, что когда обработчик jquery.validate.unobtrusive инициализирует плагин jquery.validate, он делает это в методе parseElement(), извлекая параметры, созданные методом validationInfo().

ValidationInfo() возвращает следующие параметры:

 options: {  // options structure passed to jQuery Validate's validate() method
             errorClass: "input-validation-error",
             errorElement: "span",
             errorPlacement: $.proxy(onError, form),
             invalidHandler: $.proxy(onErrors, form),
             messages: {},
             rules: {},
             success: $.proxy(onSuccess, form)
           },

Метод onErrors() в jquery.validate.unobtrusive отвечает за динамическое создание сводной панели проверки для MVC. Если вы не создаете панель сводки проверки (с @Html.ValidationSummary(), которая должна случайно содержаться в теле FORM), тогда этот метод полностью инертен и ничего не делает, так что вам не о чем беспокоиться.

function onErrors(event, validator) {  // 'this' is the form elementz
    var container = $(this).find("[data-valmsg-summary=true]"),
        list = container.find("ul");

    if (list && list.length && validator.errorList.length) {
        list.empty();
        container.addClass("validation-summary-errors").removeClass("validation-summary-valid");

        $.each(validator.errorList, function () {
            $("<li />").html(this.message).appendTo(list);
        });
    }
}

Если вы действительно хотите, вы можете отсоединить обработчик jquery.validate.unobtrusive вот так - но я бы не стал беспокоиться

 $("form").unbind("invalid-form.validate"); // unbind default MS handler

Если вам интересно, почему это работает

 $("form").data("validator").settings.submitHandler = ...

и это не работает

 $("form").data("validator").settings.invalidHandler = ...

это потому, что submitHandler явно вызывается внутри jquery.validate, когда выполняется проверка. Поэтому не имеет значения, в какой точке он установлен.

 validator.settings.submitHandler.call( validator, validator.currentForm );

но invalidHandler связан с событием во время init(), как это, поэтому, если вы установите его в своем собственном коде, будет слишком поздно

if (this.settings.invalidHandler)
    $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);

Небольшое пошаговое выполнение кода иногда очень полезно для понимания! Надеюсь, это поможет

* Убедитесь, что у вас не включена минификация в связках.

11 голосов
/ 30 июня 2012

Я предпочитаю внедрять обработчик событий, чтобы его можно было связать с ...:)

//somewhere in your global scripts
$("form").data("validator").settings.submitHandler = function (form) {
    var ret = $(form).trigger('before-submit');
    if (ret !== false) form.submit();
};

Таким образом, я могу связываться с ним где угодно ...

//in your view script(s)
$("form").bind("before-submit", function() {
    return confirm("Are you sure?");
});
1 голос
/ 14 июля 2013

Я основал это на исходном ответе, который не работал для меня.Я думаю, что все изменилось в JQuery.

Как обычно, возьмите этот код и добавьте обильную проверку ошибок: D Я использую подобный код для предотвращения двойной отправки в наших формах, и он отлично работает в IE8 + (с mvc4 и jquery 1.8.x).*

$("#myFormId").confirmAfterValidation();

// placed outside of a $(function(){ scope
jQuery.fn.confirmAfterValidation = function () {
    // do error checking first.  should be null if no handler already
    $(this).data('validator').settings.submitHandler = confirmValidForm;
};

function confirmValidForm(form) {
    var validator = $(this);
    var f = $(form);
    if (confirm("really really submit?")) {
        // unbind so our handler doesn't get called again, and submit
        f.unbind('submit').submit();
    }
        // return value is _ignored_ by jquery.validate, so we have to set
        // the flag on the validator itself, but it should cancel the submit
        // anyway if we have a submitHandler
        validator.cancelSubmit = true;
    }
}
...