如何在使用jQuery Unobtrusivevalidation时添加“submitHandler”函数?

我使用ASP.NET MVC 3中新的不显眼的validationfunction来validation表单。

所以没有编写的代码来设置jQueryvalidation来开始validation我的表单。 这一切都通过加载jQuery.validate.unobtrusive.js库来完成。

不幸的是,我需要在“你确定吗? 当表单有效但提交之前的消息框。 随着jQueryvalidation你会添加选项handleSubmit初始化时如此:

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

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

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

谢谢

不引人注目的库将附加所有forms的validation器,所以你必须这样replacesubmitHandler:

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

我发现这个问题,同时寻找一种方法来设置invalidHandler ,而不是submitHandler 。 有趣的是,当使用不显眼的validation时,不能以相同的方式设置invalidHandler

当检测到无效的表单时,该函数不会被触发:

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

这种方法工作:

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

这似乎是由于jquery.validate.unobtrusive.js脚本初始化Validate插件的方式,以及插件调用处理程序的方式。

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

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

@DGreen的解决scheme似乎是注入特殊处理的最好方法,如果表单validation失败,并且您需要执行某些操作,如显示popup式validation摘要( invalidHandler

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

@PeteHaus解决scheme是做一些事情的最好方法,如果你想阻止成功validation的表单的回发( submitHandler

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

然而,我很担心通过绑定到这样的.validate方法来重写(或不重写)什么行为 – 以及为什么我必须以不同的方式执行。 所以我查了一下源码。 我强烈build议任何想要了解这个过程的人也会这样做 – 放入一些“警告”语句或“debugging器”语句,并且很容易遵循*

无论如何,事实certificate,当jquery.validate.unobtrusive处理程序初始化jquery.validate插件时,它通过检索由validationInfo()方法创build的选项在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) }, 

onErrors()方法负责为MVCdynamic创buildvalidation摘要面板。 如果你没有创build一个validation摘要面板(带有@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 = ... 

这是因为在执行validation时, jquery.validatesubmitHandler被明确地调用。 所以它在什么地方设置并不重要。

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

但是invalidHandlerinit()这样的过程中被绑定到一个事件上,所以如果你把它设置在你自己的代码中,那就太迟了

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

通过代码的一点点,有时候会让人有很多的理解! 希望这可以帮助

*确保你没有启用捆绑的缩小。

我喜欢注入一个事件处理程序,以便它可以绑定到… 🙂

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

我以原来的答案为基础,这不适合我。 我想事情已经改变了jQuery。

像往常一样,采取这个代码,并添加大量的错误检查:DI使用类似的代码,以防止双重提交我们的forms,并在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; } }