jquery.validate.unobtrusive не работает с динамическими инъецированными элементами

Я работаю с 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 вызывает метод validate модуля проверки правильности jquery для установки всех правил и сообщений. Проблема в том, что при повторном вызове плагин не обновляет новый набор правил, данный ему.

Я нашел одно грубое решение: перед вызовом метода parse в ненавязчивой библиотеке я выкидываю шаблон проверки формы:

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

Теперь, когда метод validate вызывается ненавязчивой lib, все правила и сообщения воссоздаются, включая динамически добавленные входы.

Надеюсь это поможет

Я использую MVC 4 и JQuery 1.8, выглядит следующим образом, чтобы включить JQuery для проверки динамически вводимого содержимого через Ajax или JQuery в DOM.

Я сделал модульную функцию, которая принимает объект Jquery только что добавленного элемента. Если вы клонировали новую таблицу с id tblContacts используя tblContacts нажав кнопку, 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, отмеченное как ответ выше, я немного расширил его.

 $.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 в своем коде и собираюсь удалить его, потому что я его не использовал, что привело меня к этому вопросу 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(); 

Виола!

В случае динамического содержимого вам необходимо обновить 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'); } }); 

Я некоторое время занимался этим, отказываясь от решений и повторять попытку позже (когда у меня было свободное время, верьте или нет).

Я не уверен, изменилось бы это поведение в новых версиях jquery (мы используем 1.7.2), поскольку этот stream был создан или прокомментирован последним, но я обнаружил, что .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); 

Во-первых, я думаю, что вызов должен состоять в .validator, а не в проверке, тогда вам нужно передать идентификатор формы

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

Я попытался ответить на вопрос о виггите, и сначала все, казалось, сработало. Но через некоторое время я заметил, что валидация становится болезненно медленной, чем более динамически добавляемые элементы. Причина заключалась в том, что его решение не отвязывает обработчики событий, но каждый раз добавляет новые. Поэтому, если вы добавите 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"); 
Interesting Posts
Давайте будем гением компьютера.