Как добавить функцию «submitHandler» при использовании ненавязчивой проверки jQuery?

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

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

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

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

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

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

Спасибо


person WooWaaBob    schedule 20.01.2011    source источник
comment
кто-нибудь: есть ли официальная документация для этого от MS?   -  person Simon_Weaver    schedule 23.12.2012
comment
примечание: handleSubmit() вызывается только в том случае, если все значения формы проверяются. Он не вызывается, если у вас есть какие-либо ошибки. Это идеально подходит для запроса подтверждения, как и вы (потому что вы знаете, что все действительно), но если вам нужна специальная обработка при наличии ошибок, вы должны использовать invalidHandler - см. ответ DGreen.   -  person Simon_Weaver    schedule 24.12.2012
comment
Вместо того, чтобы ждать, пока он уже будет инициализирован, вы также можете напрямую вызвать jQuery.validator.setDefaults и любую последующую инициализацию формы. будут использовать эти настройки. Просто убедитесь, что он запускается до загрузки DOM и jQuery Validator автоматически инициализирует формы.   -  person KyleMit    schedule 28.09.2016


Ответы (5)


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

$("form").data("validator").settings.submitHandler = function (form) { alert('submit'); form.submit(); };
person petrhaus    schedule 21.01.2011
comment
Спасибо @petrhaus - хороший простой ответ, который также расширил мое понимание jQuery. - person WooWaaBob; 24.01.2011
comment
Для динамически загружаемых форм (например, диалоговое окно) вы должны сначала вызвать $.validator.unobtrusive.parse($('form')) или $('form').data вернет неопределенное значение. - person parliament; 18.02.2013
comment
Разочаровывает то, что я застрял, пытаясь понять, что пошло не так, потому что, если submitHandler был установлен в тегах ‹script› в конце документа, он работает нормально. но как только вы поместите его в готовый документ, он не будет работать. - person Seravy; 06.02.2014
comment
Я пробовал все вышеперечисленное, чтобы обработать invalidHandler, выталкивающий alert, но он не появляется. И $('form').data('validator') возвращает undefined, даже после того, как я попытался вызвать $.validator.unobtrusive.parse($('form')), как предложил @parliament. - person Shimmy Weitzhandler; 26.04.2015
comment
Я добавил этот новый вопрос. - person Shimmy Weitzhandler; 26.04.2015
comment
NB Два предупреждения. (1) При использовании форм AJAX это не сработает (см. здесь: $(theForm).trigger("sumbit")). (2) нужно избегать вызова submit в оболочке jQuery: он просто вызовет проверку и обработчик. Конечно №1 вызывает №2! Единственный способ, кажется, явно установить submitHandler на null в первый раз. - person Richard; 23.06.2015
comment
Кроме того, я использую функцию .validate() для получения объекта валидатора вместо .data("validator") на случай, если библиотека изменит свою реализацию. Так что мой код будет: $("form").validate().settings.submitHandler = function.. - person timmi4sa; 06.09.2019

Я нашел этот вопрос, когда искал способ установить 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, и способом, которым подключаемый модуль вызывает обработчик.

person DGreen    schedule 25.01.2011
comment
Примечание: подход «bind» здесь буквально такой же, как функция инициализации jquery.validate. - person Simon_Weaver; 24.12.2012
comment
помогает, кто может помочь объяснить? это выглядит не «официально», как, если я хочу определить submitHandler? - person Elaine; 15.04.2014
comment
Я пробовал все вышеперечисленное, чтобы обработать invalidHandler, выталкивающий alert, но он не появляется. И $('form').data('validator') возвращает undefined. - person Shimmy Weitzhandler; 26.04.2015
comment
Я добавил этот новый вопрос. - person Shimmy Weitzhandler; 26.04.2015

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

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);

Небольшое пошаговое выполнение кода иногда приводит к большому пониманию! Надеюсь это поможет

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

person Simon_Weaver    schedule 23.12.2012
comment
Хорошее подробное объяснение, Саймон, особенно по сравнению с моим расплывчатым ответом :) - person DGreen; 01.02.2013
comment
@DGreen мои ответы, как правило, пропорциональны количеству боли и времени, которое мне причинила проблема, но без вашего ответа это было бы намного дольше, когда я понял это! - person Simon_Weaver; 13.07.2013
comment
Я пробовал все вышеперечисленное, чтобы обработать invalidHandler, выталкивающий alert, но он не появляется. И $('form').data('validator') возвращает undefined. - person Shimmy Weitzhandler; 26.04.2015
comment
Вероятно, он сильно изменился с момента этого ответа :-( - person Simon_Weaver; 26.04.2015
comment
@Simon_Weaver, спасибо за ответ. Теперь я вижу, что это действительно работает, но только если я попытаюсь отправить форму. Есть ли событие, которое возникает при наличии ошибок проверки, даже если ошибки проверки были добавлены сервером во время предыдущей обратной передачи? - person Shimmy Weitzhandler; 26.04.2015
comment
@Simon_Weaver Я добавил этот новый вопрос. - person Shimmy Weitzhandler; 26.04.2015

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

//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?");
});
person Tracker1    schedule 30.06.2012

Я основывал это на исходном ответе, который у меня не сработал. Я думаю, что-то изменилось в 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;
    }
}
person Andrew Backer    schedule 14.07.2013