【问题标题】:How to add a 'submitHandler' function when using jQuery Unobtrusive Validation?使用 jQuery Unobtrusive Validation 时如何添加“submitHandler”函数?
【发布时间】:2011-06-12 10:23:15
【问题描述】:

我正在使用 ASP.NET MVC 3 中新的不显眼的验证功能验证表单。

所以我没有编写任何代码来设置 jQuery validate 来开始验证我的表单。这一切都是通过加载 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();
     }
  }
});

但是使用不显眼的库时不需要初始化。

在这种情况下我可以在哪里/如何添加提交处理程序有什么想法吗?

谢谢

【问题讨论】:

  • 任何人:有没有来自 MS 的官方文档?
  • 注意:handleSubmit() 仅在所有表单值都有效时才被调用。如果您有任何错误,则不会调用它。它非常适合像您一样要求确认(因为您知道一切都是有效的),但是如果您想在出现错误时进行特殊处理,则必须使用 invalidHandler - 请参阅 DGreen 的回答
  • 您也可以直接调用jQuery.validator.setDefaults,而不是等到它已经初始化,任何后续的表单初始化都将使用这些设置。只需确保它在加载 DOM 之前运行,并且 jQuery Validator 会自动初始化表单。

标签: jquery asp.net-mvc-3 jquery-validate unobtrusive-validation


【解决方案1】:

不显眼的库将在所有表单上附加验证器,因此您必须以这种方式替换 submitHandler:

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

【讨论】:

  • 感谢@petrhaus - 很好的简单答案,也增加了我对 jQuery 的理解。
  • 对于动态加载的表单(例如对话框),您必须首先调用 $.validator.unobtrusive.parse($('form')) 否则 $('form').data 将返回 undefined。
  • 对此令人沮丧的部分是,我一直在试图找出问题所在,因为如果在文档末尾的
  • 我尝试了以上所有方法来处理弹出invalidHandleralert,但它没有弹出。并且$('form').data('validator') 返回undefined,即使在我尝试按照@parliament 的建议调用$.validator.unobtrusive.parse($('form')) 之后。
  • NB 对此有两个警告。 (1) 如果使用 AJAX 表单,它将不起作用(请参阅here:$(theForm).trigger("sumbit"))。 (2) 需要避免在 jQuery 包装器上调用 submit:它只会调用验证和处理程序。当然#1导致#2!唯一的方法似乎是第一次将submitHandler 明确设置为null
【解决方案2】:

我在寻找设置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 插件的方式,以及插件调用处理程序的方式。

【讨论】:

  • 注意:这里的“绑定”方法与 jquery.validate init 函数的执行方式完全相同
  • 求助,谁能帮忙解释一下?它看起来不是“官方”方式,如果我想定义 submitHandler 怎么办?
  • 我尝试了以上所有方法来处理弹出invalidHandleralert,但它没有弹出。 $('form').data('validator') 返回 undefined
  • 我添加了this 新问题。
【解决方案3】:

我更喜欢注入一个事件处理程序,以便它可以绑定到... :)

//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?");
});

【讨论】:

    【解决方案4】:

    以下发现可能有助于理解两者之间的区别:

    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 插件时,它通过检索validationInfo() 方法创建的选项在parseElement() 方法中这样做。

    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)
               },
    

    jquery.validate.unobtrusive 中的onErrors() 方法负责为 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 = ...
    

    这是因为在执行验证时,submitHandlerjquery.validate 内部被显式调用。因此,无论何时设置它都无关紧要。

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

    但是invalidHandlerinit() 期间绑定到一个事件,所以如果你在自己的代码中设置它就太晚了

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

    有时,稍微单步执行代码会加深理解!希望这会有所帮助

    *确保您没有启用捆绑包中的缩小功能。

    【讨论】:

    • 很好的详细解释西蒙,尤其是与我模糊的答案相比:)
    • @DGreen 我的答案往往与问题给我带来的痛苦和时间成正比 - 但如果没有你的回答,到我想通的时候,它会更长!
    • 我尝试了以上所有方法来处理弹出invalidHandleralert,但它没有弹出。 $('form').data('validator') 返回 undefined
    • 自从这个答案以来,它可能发生了很大变化:-(
    • @Simon_Weaver,感谢您的回复。我现在看到它确实有效,但前提是我尝试提交表单。是否存在任何验证错误时引发的事件,即使验证错误是由服务器在之前的回发期间添加的?
    【解决方案5】:

    我基于原始答案,这对我不起作用。我想 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多