我正在使用ASP.Net MVC3
,使用客户端验证的更简单方法是启用jquery.validate.unobtrusive
。一切正常,对于服务器中的正确内容。
但是,当我尝试使用javascript注入一些新的“输入”时,我知道需要调用$.validator.unobtrusive.parse()
以重新绑定验证。但是,所有这些动态注入字段仍无法正常工作。
更糟糕的是,我尝试使用手动绑定jquery.validate
,但也不起作用。有什么想法吗?
我正在使用ASP.Net MVC3
,使用客户端验证的更简单方法是启用jquery.validate.unobtrusive
。一切正常,对于服务器中的正确内容。
但是,当我尝试使用javascript注入一些新的“输入”时,我知道需要调用$.validator.unobtrusive.parse()
以重新绑定验证。但是,所有这些动态注入字段仍无法正常工作。
更糟糕的是,我尝试使用手动绑定jquery.validate
,但也不起作用。有什么想法吗?
Answers:
我为jquery.validate.unobtrusive库创建了一个扩展,该扩展针对我的情况解决了该问题-可能很有趣。
http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/
$.validator.unobtrusive.parse()
。另外,它似乎仅添加新规则,而不选择更新现有规则?
我尝试了Xhalent的方法,但不幸的是,它对我没有用。罗宾的方法行得通而且行不通。它对于动态添加的元素非常有用,但是,如果您尝试使用JQuery从DOM中删除所有验证属性和范围,则验证库仍将尝试对其进行验证。
但是,如果除“ validationData”之外还删除了表单的“ unobtrusiveValidation”数据,它就像一种用于动态添加和删除要验证或未验证的元素的超级按钮。
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
validator
未定义吗?我同时引用了validation和validation.unobtrusive。验证有效,直到我调用这些代码
$('#form').validate({ignore: ""})
我实际上真的很喜欢@viggity和@Robins解决方案的简单性,因此我将其变成了一个快速的小插件:
(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()。最初从服务器加载表单时,表单将由非侵入式库自动解析。当您将输入元素动态添加到表单中并再次调用$ .validator.unobtrusive.parse()时,它将不起作用。parseElement()也是如此。
不显眼的lib调用jquery validate插件的validate方法来设置所有规则和消息。问题是,再次调用该插件时,它不会更新其给定的新规则集。
我找到了一个简单的解决方案:在不打扰的lib上调用parse方法之前,我丢弃了表单验证器:
$('yourForm').removeData("validator");
现在,当不打扰的lib调用validate方法时,将重新创建所有规则和消息,包括动态添加的输入。
希望这可以帮助
我正在使用MVC 4和JQuery 1.8,看起来需要以下代码才能使Jquery验证通过Ajax或Jquery向DOM中动态注入的内容。
我做了一个模块化的函数,可以接受新添加元素的Jquery对象。如果tblContacts
单击按钮后使用Jquery 克隆了一个ID为ID的新表,请在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解决方案中,我对它进行了扩展。
$.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的解决方案相同,但是我添加了删除从dom中删除元素的规则的功能。因此,当您从Dom中删除元素并希望删除那些验证规则时,还可以调用:
$.validator.unobtrusive.unparseContent('input.something');
我在代码中找到@Xhalent的代码脚本,并打算删除它,因为我没有使用它,这导致我遇到这个SO问题。
这段代码非常干净和简单:
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扩展,只需使用选择器即可获取表单:
$('#formStart').unobtrusiveValidationForceBind();
中提琴!
我尝试了无懈可击的回答,但起初一切似乎都可行。但是过了一会儿,我注意到随着添加的内容更加动态,验证变得很痛苦。原因是他的解决方案没有解除绑定事件处理程序,而是每次都添加新的处理程序。因此,如果添加5个项目,则验证将执行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");
如果是动态内容,则需要如下更新“非侵入式验证”,并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');
}
});
我已经摆弄了一段时间,放弃了解决方案并稍后再试(当我有空闲时间时,信不信由你)。
自从此线程最后创建或注释以来,我不确定这种行为是否会在较新版本的jquery(我们正在使用1.7.2)中更改,但是我发现.parseElement(inputElement)
当我尝试向表单中添加动态创建的元素时,这种方法工作正常已经加载了验证器。@jamesfm(2011年2月15日)已经在上面的评论之一中建议过这一点,但是我在从事此工作的头几次就忽略了它。因此,我将其添加为一个单独的答案以使其更明显,因为我认为这是一个很好的解决方案,并且不需要太多开销。它可能与后续答案中提出的所有问题都不相关,但我认为这将是对原始问题的解决方案。这是我的工作方式:
//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);
如果您需要添加和删除某些东西(可能已经显示了一些错误),这就是我自带的。它主要基于此问题页面上的不同想法。我使用内置方法,destroy()
而不仅仅是删除JQuery验证的data属性。
function resetValidator($form: JQuery) {
$form.validate().destroy();
//reset unobtrusive validation summary, if it exists
$form.find("[data-valmsg-summary=true]")
.removeClass("validation-summary-errors")
.addClass("validation-summary-valid")
.find("ul").empty();
//reset unobtrusive field level, if it exists
$form.find("[data-valmsg-replace]")
.removeClass("field-validation-error")
.addClass("field-validation-valid")
.empty();
$form.removeData("unobtrusiveValidation");
}
在动态修改表单中的输入之前,请先调用它。然后,您可以在之后重新初始化验证。
resetValidator($form);
//add or remove inputs here ...
$.validator.unobtrusive.parse($form);
注意:如果某些或所有输入已通过验证并且有错误,这些错误将被重置...但是它们将在下一次验证时正确返回。