Ответ 1
Я создал расширение для библиотеки jquery.validate.unobtrusive, которая решила эту проблему для моей ситуации - она может представлять интерес.
http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/
Я работаю с ASP.Net MVC3
, более простой способ использования проверки клиента будет включать jquery.validate.unobtrusive
. Все работает отлично, для вещей, которые прямо с сервера.
Но когда я пытаюсь ввести некоторые новые "входы" с помощью javascript, и я знал, что мне нужно вызвать $.validator.unobtrusive.parse()
, чтобы переустановить проверки. Но все же все эти динамические инжекционные поля не функционируют.
Хуже того, я пытаюсь вручную привязать с помощью jquery.validate
, и он не работает. Любые мысли?
Я создал расширение для библиотеки jquery.validate.unobtrusive, которая решила эту проблему для моей ситуации - она может представлять интерес.
http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/
Я пробовал подход Xhalent, но, к сожалению, он не работал у меня. Подход Робин работал и не работал. Он отлично справился с динамически добавленными элементами, но если вы попытались использовать JQuery для удаления всех атрибутов проверки и интервалов из DOM, библиотека проверки еще попыталась бы проверить их.
Однако, если вы удаляете данные "ненавязчивые данные" в дополнение к "validationData", она работает как очарование для динамического добавления и удаления элементов, которые вы хотите проверить или не проверить.
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");
Мне действительно нравится простота решения @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 для установки всех правил и сообщений. Проблема в том, что при повторном вызове плагин не обновляет новый набор правил.
Я нашел одно грубое решение: перед вызовом метода parse в ненавязчивой lib, я выбрал шаблон проверки формы:
$('yourForm').removeData("validator");
Теперь, когда метод validate вызывается ненавязчивой lib, все правила и сообщения воссоздаются, включая динамически добавленные входы.
Надеюсь, что это поможет
Я использую MVC 4 и JQuery 1.8, выглядит следующим образом, чтобы включить JQuery для проверки динамического ввода содержимого через Ajax или JQuery в DOM.
Я сделал модульную функцию, которая принимает объект JQuery вновь добавленного элемента.
Если вы клонировали новую таблицу с id tblContacts
с помощью Jquery по щелчку кнопки, включите функцию ниже в файл 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');
Почему бы не использовать функцию правил непосредственно из документа проверки jquery. Вот так:
$('#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 код script в своем коде и собираюсь удалить его, потому что я не использовал его, что привело меня к этому вопросу 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();
Viola!
В случае динамического содержимого вам необходимо обновить Unobtrusive Validations, как показано ниже, и проверить, действительно ли 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');
}
});
Во-первых, я думаю, что вызов должен быть .validator, а не проверять, тогда вам нужно передать идентификатор формы
$.validator.unobtrusive.parse("#id");
Я некоторое время занимался этим, отказываясь от решений и повторять попытку позже (когда у меня было свободное время, верьте или нет).
Я не уверен, изменилось бы это поведение в новых версиях jquery (мы используем 1.7.2), поскольку этот поток был создан или прокомментирован последним, но я обнаружил, что .parseElement(inputElement)
отлично работает, когда я пытаюсь добавить динамически созданных элементов в форму, на которой уже загружен валидатор.
Это уже было предложено @jamesfm (Feb 15'11) в одном из комментариев выше, но я упустил это в первые несколько раз, когда я работал над этим. Поэтому я добавляю его как отдельный ответ, чтобы сделать его более очевидным и потому, что я думаю, что это хорошее решение и не требует слишком больших накладных расходов. Это может быть не актуально для всех вопросов, затронутых в последующих ответах, но я думаю, что это будет решение первоначального вопроса. Вот как я получил свою работу:
//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);
Я пробовал отвечать на виггит, и сначала все, казалось, сработало. Но через некоторое время я заметил, что валидация становится болезненно медленной, чем более динамически добавляемые элементы. Причина заключалась в том, что его решение не отвязывает обработчики событий, но каждый раз добавляет новые. Поэтому, если вы добавите 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");