jquery.validate.unobtrusive不能使用dynamic注入的元素

我正在与ASP.Net MVC3 ,更简单的方法来使用客户端validation将启用jquery.validate.unobtrusive 。 一切工作正常,从服务器的东西。

但是当我尝试用javascript注入一些新的“input”时,我知道我需要调用$.validator.unobtrusive.parse()来重新validationvalidation。 但是,所有这些dynamic注入的域都不起作用。

更糟糕的是,我尝试手动绑定使用jquery.validate ,它也不工作。 有什么想法吗?

我已经为jquery.validate.unobtrusive库创build了一个扩展来解决这个问题,这可能是我感兴趣的。

http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/

我尝试了Xhalent的方法,但不幸的是它不适合我。 罗宾的方法确实奏效,并没有奏效。 它对于dynamic添加的元素非常适用,但是如果您尝试使用JQuery从DOM删除所有validation属性和跨度,则validation库仍然会尝试validation它们。

但是,除了“validationData”,如果删除了表单的“unobtrusiveValidation”数据,它就像一个魅力一样dynamic添加和删除要validation或未validation的元素。

 $("form").removeData("validator"); $("form").removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse("form"); 

我其实很喜欢@viggity和@Robins解决scheme的简单性,所以我把它变成了一个快速的小插件:

 (function ($) { $.fn.updateValidation = function () { var $this = $(this); var form = $this.closest("form") .removeData("validator") .removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse(form); return $this; }; })(jQuery); 

用法示例:

 $("#DischargeOutcomeNumberOfVisits") .attr("data-val-range-min", this.checked ? "1" : "2") .updateValidation(); 

我有同样的问题。 我发现无法在同一个表单上调用$ .validator.unobtrusive.parse()两次。 最初从服务器加载表单时,表单由不显眼的库自动分析。 当您将input元素dynamic添加到表单并再次调用$ .validator.unobtrusive.parse()时,它将不起作用。 parseElement()也是一样。

unobtrusive库调用jquery validate插件的validate方法来设置所有的规则和消息。 问题是,再次调用时,插件不会更新它给定的新规则集。

我发现一个粗略的解决scheme:在unobstrusive库调用parsing方法之前,我扔掉表单validation程序:

 $('yourForm').removeData("validator"); 

现在,当不显眼的lib调用validate方法时,所有规则和消息都被重新创build,包括dynamic添加的input。

希望这可以帮助

我正在使用MVC 4和JQuery 1.8,看起来像下面这段代码是需要启用Jquerydynamic注入内容通过Ajax或Jquery到DOMvalidation。

我做了一个模块化的function,接受新添加的元素的Jquery对象。 如果你点击一个button,使用tblContacts克隆了一个新的id为tblContacts表,然后在你的js文件中包含下面的函数

 function fnValidateDynamicContent(element) { var currForm = element.closest("form"); currForm.removeData("validator"); currForm.removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse(currForm); currForm.validate(); // This line is important and added for client side validation to trigger, without this it didn't fire client side errors. } 

并像这样调用它:

 fnValidateDynamicContent("#tblContacts") 

从Xhalent的解决scheme标记为上面的答案,我扩大了一点。

 $.validator.unobtrusive.parseDynamicContent = function (selector) { var $selector = $(selector), $jqValUnob = $.validator.unobtrusive, selectorsDataValAttr = $selector.attr('data-val'), $validationInputs = $selector.find(':input[data-val=true]'); if ((selectorsDataValAttr !== 'true') && ($validationInputs.length === 0)) { return; } if (selectorsDataValAttr === 'true') { $jqValUnob.parseElement(selector, true); } $validationInputs.each(function () { $jqValUnob.parseElement(this, true); }); //get the relevant form var $form = $selector.first().closest('form'); $jqValUnob.syncValdators($form); }; /* synchronizes the unobtrusive validation with jquery validator */ $.validator.unobtrusive.syncValdators = function ($form) { if ($.hasData($form[0])) { var unobtrusiveValidation = $form.data('unobtrusiveValidation'), validator = $form.validate(); // add validation rules from unobtrusive to jquery $.each(unobtrusiveValidation.options.rules, function (elname, elrules) { if (validator.settings.rules[elname] == undefined) { var args = {}; $.extend(args, elrules); args.messages = unobtrusiveValidation.options.messages[elname]; $("[name='" + elname + "']").rules("add", args); } else { $.each(elrules, function (rulename, data) { if (validator.settings.rules[elname][rulename] == undefined) { var args = {}; args[rulename] = data; args.messages = unobtrusiveValidation.options.messages[elname][rulename]; $("[name='" + elname + "']").rules("add", args); } }); } }); // remove all validation rules from jquery that arn't in unobtrusive $.each(validator.settings.rules, function (elname, elrules) { if (unobtrusiveValidation.options.rules[elname] === undefined) { delete validator.settings.rules[elname]; } else { $.each(elrules, function (rulename, data) { if (rulename !== "messages" && unobtrusiveValidation.options.rules[elname][rulename] === undefined) { delete validator.settings.rules[elname][rulename]; } }); } }); } }; $.validator.unobtrusive.unparseContent = function (selector) { var $selector = $(selector); // if its a text node, then exit if ($selector && $selector.length > 0 && $selector[0].nodeType === 3) { return; } var $form = $selector.first().closest('form'), unobtrusiveValidation = $form.data('unobtrusiveValidation'); $selector.find(":input[data-val=true]").each(function () { removeValidation($(this), unobtrusiveValidation); }); if ($selector.attr('data-val') === 'true') { removeValidation($selector, unobtrusiveValidation); } $.validator.unobtrusive.syncValdators($form); }; function removeValidation($element, unobtrusiveValidation) { var elname = $element.attr('name'); if (elname !== undefined) { $element.rules('remove'); if (unobtrusiveValidation) { if (unobtrusiveValidation.options.rules[elname]) { delete unobtrusiveValidation.options.rules[elname]; } if (unobtrusiveValidation.options.messages[elname]) { delete unobtrusiveValidation.options.messages[elname]; } } } } 

所以基本上它和Xhalent的解决scheme仍然是一样的,但是我添加了删除dom元素的规则。 所以,当你从Dom中删除元素,并且你想要删除这些validation规则时,请调用:

 $.validator.unobtrusive.unparseContent('input.something'); 

为什么不直接从jQueryvalidation文档使用规则function 。 喜欢这个:

 $('#newField0').rules('add', { required: true, minlength: 2 }); //use Html.ValidationMessage will renders a span element, unobtrusive need it to display errors $('@Html.ValidationMessage("newField0")').insertAfter('#newField0'); 

我在代码中发现了@ Xhalent的代码脚本,并将删除它,因为我没有使用它,这导致我这个问题。

这段代码很干净简单:

 jQuery.fn.unobtrusiveValidationForceBind = function () { //If you try to parse a form that is already parsed it won't update var $form = this .removeData("validator") /* added by the raw jquery.validate plugin */ .removeData("unobtrusiveValidation"); /* added by the jquery unobtrusive plugin */ $form.bindUnobtrusiveValidation(); } 

然后,要调用这个jQuery扩展,只需使用select器来抓取你的表单:

 $('#formStart').unobtrusiveValidationForceBind(); 

中提琴!

我一直在摆弄这一段时间,解决scheme,并稍后再试(当我有一些业余时间,信不信由你)。

我不确定这个行为是否会在新版本的jquery(我们使用1.7.2)中发生变化,因为这个线程是最后创build或注释的,但是我发现.parseElement(inputElement)工作正常,当我尝试dynamic添加创build的元素已经有一个validation器加载的窗体。 @jamesfm(11年2月15日)已经在上面的一个评论中提到过这个问题,但是我在开始的几次工作中忽略了这个问题。 所以我把它作为一个单独的答案join,使其更加明显,因为我认为这是一个很好的解决scheme,不需要太多的开销。 这可能与后续答案中提出的所有问题无关,但我认为这将是对原始问题的解决scheme。 以下是我的工作方式:

 //row & textarea created dynamically by an async ajax call further up in the code var row = ...; //row reference from somewhere var textarea = row.find("textarea"); textarea.val("[someValue]"); //add max length rule to the text area textarea.rules('add', { maxlength: 2000 }); //parse the element to enable the validation on the dynamically added element $.validator.unobtrusive.parseElement(textarea); 

首先,我认为这个调用应该是.validator,而不是validation,那么你需要传入表单的id

 $.validator.unobtrusive.parse("#id"); 

我尝试了他的回答,起初一切似乎都奏效了。 但过了一会儿,我发现validation变得痛苦缓慢,我添加更dynamic的项目。 原因是他的解决scheme并没有解除绑定事件处理程序,而是每次都添加新的处理程序。 所以如果添加5个项目,validation会执行6次,而不是只执行一次。 要解决这个问题,你必须解除removeData调用的事件。

 $("form").removeData("validator") .removeData("unobtrusiveValidation") .off("submit.validate click.validate focusin.validate focusout.validate keyup.validate invalid-form.validate"); $.validator.unobtrusive.parse("form"); 

在dynamic内容的情况下,您需要更新不显眼的validation如下,并检查Form是否有效,而提交。

 function UpdateUnobtrusiveValidations(idForm) { $(idForm).removeData("validator").removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse($(idForm)); }; $('#idDivPage').on('click', '#idSave', function (e) { e.preventDefault(); if (!$('#idForm').valid()) { // Form is invalid … so return return false; } else { // post data to server using ajax call // update Unobtrusive Validations again UpdateUnobtrusiveValidations('#idForm'); } });