如何在使用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.validate
在submitHandler
被明确地调用。 所以它在什么地方设置并不重要。
validator.settings.submitHandler.call( validator, validator.currentForm );
但是invalidHandler
在init()
这样的过程中被绑定到一个事件上,所以如果你把它设置在你自己的代码中,那就太迟了
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; } }