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'); } });