validator validate net mvc form example before asp asp.net-mvc-3 jquery-validate unobtrusive-validation

asp.net mvc 3 - net - jquery.validate.unobtrusive no funciona con elementos dinámicos inyectados



mvc validation before submit (12)

¿Por qué no utilizar la función de reglas directamente desde el documento de validación de jquery? Me gusta esto:

$(''#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'');

Estoy trabajando con ASP.Net MVC3 , la manera más fácil de usar la validación del cliente sería habilitar jquery.validate.unobtrusive . Todo funciona bien, para cosas que son correctas desde el servidor.

Pero cuando trato de inyectar algunas ''entradas'' nuevas con javascript, y sabía que debía llamar a $.validator.unobtrusive.parse() para volver a enlazar las validaciones. Pero aún así, todos esos campos dinámicos inyectados no están funcionando.

Peor aún, intento vincular manualmente usando jquery.validate y tampoco funciona. ¿Alguna idea?



En el caso de los contenidos dinámicos, debe actualizar Validación discreta como se indica a continuación y verificar si el Form es válido durante el envío.

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''); } });


En primer lugar, creo que la llamada debe ser .validator, no validar, entonces debe pasar la identificación del formulario

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


Encontré el script de código de @ Xhalent en mi código y lo iba a eliminar porque no lo estaba usando, lo que me llevó a esta pregunta SO.

Este código es bastante limpio y simple:

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(); }

Luego, para llamar a esta extensión de jQuery, simplemente use un selector para tomar su forma:

$(''#formStart'').unobtrusiveValidationForceBind();

¡Viola!


Estoy teniendo el mismo problema. Descubrí que no es posible llamar $ .validator.unobtrusive.parse () en el mismo formulario dos veces. Al cargar el formulario inicialmente desde el servidor, el formulario es analizado automáticamente por la biblioteca no intrusiva. Cuando agrega un elemento de entrada dinámicamente al formulario y llama de nuevo $ .validator.unobtrusive.parse (), no funcionará. Lo mismo ocurre con parseElement ().

La lib discreta llama al método de validación del complemento jquery validate para establecer todas las reglas y mensajes. El problema es que, cuando se vuelve a llamar, el complemento no actualiza el nuevo conjunto de reglas dado.

Encontré una solución cruda: antes de llamar al método parse en la libre discreción, tiro el validador de formulario:

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

Ahora, cuando la discreta lib llama al método de validación, todas las reglas y mensajes se vuelven a crear, incluidas las entradas añadidas dinámicamente.

Espero que esto ayude


Estoy usando MVC 4 y JQuery 1.8, parece que se necesita el siguiente fragmento de código para permitir que Jquery valide contenido inyectado dinámicamente a través de Ajax, o Jquery en el DOM.

He hecho una función modular que acepta el objeto Jquery del elemento recién agregado. Si ha clonado una nueva tabla con id tblContacts utilizando Jquery al hacer clic en un botón, incluya la siguiente función en su archivo 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. }

y llámalo así:

fnValidateDynamicContent("#tblContacts")


He estado jugando con esto por un tiempo, descartando soluciones e intentando de nuevo más tarde (cuando tenía algo de tiempo libre, lo creas o no).

No estoy seguro de si este comportamiento hubiera cambiado en las versiones más nuevas de jquery (estamos usando 1.7.2) ya que este subproceso fue creado o comentado al final, pero encontré que .parseElement(inputElement) funciona bien cuando intento agregar dinámicamente creado elementos a una forma que ya tiene un validador cargado. Esto ya fue sugerido por @jamesfm (15 de febrero de 2011) en uno de los comentarios anteriores, pero lo pasé por alto las primeras veces que trabajé en esto. Así que lo estoy agregando como una respuesta separada para hacerlo más obvio y porque creo que es una buena solución y no requiere mucha sobrecarga. Puede que no sea relevante para todas las cuestiones planteadas en las respuestas posteriores, pero creo que sería una solución a la pregunta original. Así es como hice que el mío funcionara:

//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);


Intenté la respuesta de Viggity y al principio todo pareció funcionar. Pero después de un tiempo noté que la validación se vuelve extremadamente lenta cuanto más dinámicamente agregué elementos. La razón fue que su solución no desvincula a los manejadores de eventos, sino que agrega nuevos cada vez. Entonces, si agrega 5 elementos, la validación se ejecuta 6 veces en lugar de solo una vez. Para solucionar esto, debe desvincular los eventos, además, de las llamadas a removeData.

$("form").removeData("validator") .removeData("unobtrusiveValidation") .off("submit.validate click.validate focusin.validate focusout.validate keyup.validate invalid-form.validate"); $.validator.unobtrusive.parse("form");


Probé el enfoque de Xhalent, pero desafortunadamente no funcionaba para mí. El enfoque de Robin funcionó y no funcionó. Funcionó muy bien para los elementos añadidos dinámicamente, pero si intentaba usar JQuery para eliminar todos los atributos de validación y los tramos del DOM, la biblioteca de validación aún intentaría validarlos.

Sin embargo, si elimina los datos de "discreción validación" del formulario además de "validationData", funcionó como un amuleto para agregar y eliminar dinámicamente los elementos que desea validar o no validados.

$("form").removeData("validator"); $("form").removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse("form");


Realmente me gusta la simplicidad de la solución @viggity y @Robins, así que la convertí en un pequeño complemento rápido:

(function ($) { $.fn.updateValidation = function () { var $this = $(this); var form = $this.closest("form") .removeData("validator") .removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse(form); return $this; }; })(jQuery);

Ejemplo de uso:

$("#DischargeOutcomeNumberOfVisits") .attr("data-val-range-min", this.checked ? "1" : "2") .updateValidation();


Tomando de la solución de Xhalent marcada como la respuesta anterior, la amplié un poco.

$.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]; } } } }

Así que, básicamente, todavía funciona igual que la solución de Xhalent anterior, pero he añadido la posibilidad de eliminar las reglas de los elementos que eliminas del dominio. Por lo tanto, cuando elimina elementos de la Dom y desea eliminar esas reglas de validación también, llame a:

$.validator.unobtrusive.unparseContent(''input.something'');