49

我正在使用 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();
     }
  }
});

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

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

谢谢

4

5 回答 5

78

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

$("form").data("validator").settings.submitHandler = function (form) { alert('submit'); form.submit(); };
于 2011-01-21T22:22:51.817 回答
63

我在寻找设置 的方法时发现了这个问题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插件的方式,以及插件调用处理程序的方式。

于 2011-01-25T22:46:03.980 回答
35

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

submitHandler:在表单验证成功时调用 - 就在服务器回发之前
invalidHandler:如果验证失败并且没有回发则调用

如果表单验证失败并且您需要执行诸如显示弹出验证摘要(invalidHandler)之类的操作,@DGreen 的解决方案似乎绝对是注入特殊处理的最佳方式

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

如果您想防止回发成功验证的表单(submitHandler) ,@PeteHaus 解决方案是最好的方法

$("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);

有时,稍微单步执行代码会产生很多理解!希望这可以帮助

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

于 2012-12-23T21:15:23.117 回答
11

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

//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?");
});
于 2012-06-30T05:59:42.780 回答
1

我基于原始答案,这对我不起作用。我想 jQuery 的情况已经发生了变化。

像往常一样,使用这段代码并添加大量的错误检查:DI 使用类似的代码来防止在我们的表单上重复提交,并且它在 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;
    }
}
于 2013-07-14T13:15:32.790 回答