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