如何在使用jQuery Unobtrusive Validation时添加'submitHandler'函数?

时间:2011-01-20 12:18:40

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

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

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

在这种情况下我可以在何处/如何添加提交处理程序?

THX

5 个答案:

答案 0 :(得分:65)

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

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

答案 1 :(得分:61)

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

答案 2 :(得分:33)

以下结果可能有助于理解:

之间的区别

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

,则调用

@ DGreen的解决方案肯定是注入特殊处理的最佳方式,如果表单验证失败并且您需要执行某些操作,例如显示弹出式验证摘要( invalidHandler

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

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

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

稍微踩一下代码有时候会有很多理解!希望这有帮助

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

答案 3 :(得分: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?");
});

答案 4 :(得分:1)

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