所以,我从this Microsoft provided Example获取了一些代码,它允许我使用jquery validate unobtrusive库来解析从我的服务器返回的验证错误消息并在UI中显示它们。他们有一个video demonstrating this。所以,这是我正在使用的Javascript代码:
$.validator.addMethod("failure", function () { return false; });
$.validator.unobtrusive.adapters.addBool("failure");
$.validator.unobtrusive.revalidate = function (form, validationResult) {
$.removeData(form[0], 'validator');
var serverValidationErrors = [];
for (var property in validationResult) {
//var elementId = property.toLowerCase();
var item = form.find('#' + property);
if (item.length < 1) { item = form.find('#' + property.replace('.', '_')); }
serverValidationErrors.push(item);
item.attr('data-val-failure', validationResult[property].join(', '));
jQuery.validator.unobtrusive.parseElement(item[0]);
}
form.valid();
$.removeData(form[0], 'validator');
$.each(serverValidationErrors, function () {
this.removeAttr('data-val-failure');
jQuery.validator.unobtrusive.parseElement(this[0]);
});
};
那么在句柄错误函数中的一个AJAX表单后,我会做这样的事情:
$.validator.unobtrusive.revalidate(form, { 'PhysicalAddress.CityName': ['You must select a valid city'] });
其中 PhysicalAddress.CityName 是我的viewmodel属性和html输入字段的名称。因此,它知道将验证消息放在正确的html元素旁边。
这有效1次。然后当他们再次点击提交并且我的代码再次调用 unobtrusive.revalidate 方法时......它不起作用。它只显示验证消息一次,之后验证消息就会消失。
有没有人知道为什么会发生这种情况?...我逐步完成了revalidate方法并且没有抛出任何错误,一切看起来都应该有效..但由于某种原因,不引人注意的库不是重新绑定验证错误消息。
由于
答案 0 :(得分:3)
这个行为可能取决于jQuery验证插件的已知问题:为元素动态添加新的验证规则只运行一次!进一步的尝试被拒绝,因为插件认为它们是重复尝试来定义已定义的规则。
这就是为什么$.validator.unobtrusive.parse
在添加新创建的内容时不起作用的原因(例如,当您向项目集合添加新行时)。 $.validator.unobtrusive.parse
有一个补丁,您可能会尝试将其应用于revalidate函数....但最好以不同的方式从头开始重写它。 revalidate函数使用验证插件只是为了将所有验证错误放在正确的位置,然后它尝试重置验证插件的状态。但是,从表单中删除验证器对象不足以取消所有已完成的工作,因为form.data('unobtrusiveValidation')
中包含另一个对象,其中form是包含要验证的表单的变量...此数据不会被重置revalidate函数...并且不能重置,因为重置它们会导致取消所有客户端验证规则。
也许这个问题已在最后一个版本的验证插件中得到解决,因此请尝试使用nuget更新到上一个版本。
如果这不能解决您的问题,我可以向您传递一个以完全不同的方式实现的类似功能(它模仿服务器在服务器端执行的操作,以显示服务器端错误)。它将包含在即将推出的Mvc Controls工具包中。但是,如果你给我几天(我将非常忙碌2天),我可以从那里提取它的依赖项,以便你可以使用它。如果您有兴趣,请告诉我。
我承诺的代码下面。它需要一个元素为:
的数组{
id:id of the element in error
errors:array of strings errors associated to the element
}
它接受每个元素的几个错误,但只显示每个元素的第一个错误 id与名称不同,因为。 []另一个特殊字符被_
替换您可以使用
将名称转换为服务器上的IDhtmlName.Replace('$', '_').Replace('.', '_').Replace('[', '_').Replace(']', '_');
或在javascript中的客户端上:
name.replace(/[\$\[\]\.]/g, '_');
function remoteErrors(jForm, errors) {
//////////
function inner_ServerErrors(elements) {
var ToApply = function () {
for (var i = 0; i < elements.length; i++) {
var currElement = elements[i];
var currDom = $('#' + currElement.id);
if (currDom.length == 0) continue;
var currForm = currDom.parents('form').first();
if (currForm.length == 0) continue;
if (!currDom.hasClass('input-validation-error'))
currDom.addClass('input-validation-error');
var currDisplay = $(currForm).find("[data-valmsg-for='" + currElement.name + "']");
if (currDisplay.length > 0) {
currDisplay.removeClass("field-validation-valid").addClass("field-validation-error");
replace = $.parseJSON(currDisplay.attr("data-valmsg-replace")) !== false;
if (replace) {
currDisplay.empty();
$(currElement.errors[0]).appendTo(currDisplay);
}
}
}
};
setTimeout(ToApply, 0);
}
/////////
jForm.find('.input-validation-error').removeClass('input-validation-error');
jForm.find('.field-validation-error').removeClass('field-validation-error').addClass('field-validation-valid');
var container = jForm.find("[data-valmsg-summary=true]");
list = container.find("ul");
list.empty();
if (errors.length > 0) {
$.each(errors, function (i, ival) {
$.each(ival.errors, function (j, jval) {
$("<li />").html(jval).appendTo(list);
});
});
container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
inner_ServerErrors(errors);
setTimeout(function () { jForm.find('span.input-validation-error[data-element-type]').removeClass('input-validation-error') }, 0);
}
else {
container.addClass("validation-summary-valid").removeClass("validation-summary-errors");
}
}
function clearErrors(jForm) {
remoteErrors(jForm, []);
}