Pregunta

Estoy trabajando con ASP.Net MVC3, la manera más fácil de utilizar la validación del cliente estaría permitiendo al jquery.validate.unobtrusive. Todo funciona bien, para la materia que sea adecuado desde el servidor.

Pero cuando intento de inyectar algunas nuevas entradas '' con javascript, y sabía que necesito $.validator.unobtrusive.parse() llamada a volver a enlazar las validaciones. Pero aún así, todos aquellos dinámica inyecta campos no están funcionando.

Lo que es peor, que intenta enlazar de forma manual utilizando jquery.validate y que no está funcionando bien. ¿Alguna idea?

¿Fue útil?

Solución

He creado una extensión para la biblioteca jquery.validate.unobtrusive que resuelve este problema para mi situación -. Que podría ser de interés

http://xhalent.wordpress.com/2011/ 01/24 / aplicar-discreto-validación-a-dinámico-content /

Otros consejos

He intentado el enfoque de Xhalent pero por desgracia no estaba trabajando para mí. El enfoque de Robin hizo el trabajo y no funcionaba. Se trabajó mucho para los elementos añadidos de forma dinámica, pero si se trató de utilizar jQuery para eliminar todos los atributos de validación y abarca desde el DOM, la biblioteca de validación todavía trataría de validarlos.

Sin embargo, si se quita de datos "unobtrusiveValidation" del formulario, además de "validationData", funcionó como un encanto para añadir y eliminar elementos que desea validado o no validado de forma dinámica.

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

De hecho, me gusta mucho la simplicidad de la solución y @viggity @Robins, por lo que la convirtió en un plugin poco rápida:

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

Estoy teniendo el mismo problema. He descubierto que no es posible llamar .validator.unobtrusive.parse $ () de la misma forma dos veces. Al cargar el formulario inicialmente desde el servidor de la forma se analiza automáticamente por la biblioteca discreta. Cuando se agrega un elemento de entrada de forma dinámica a la forma y llama a $ .validator.unobtrusive.parse () de nuevo, no va a funcionar. Lo mismo vale para parseElement ().

El lib discreta llama al método de validación de la jQuery plugin para validar establecer todas las reglas y mensajes. El problema es que, cuando se le llama de nuevo, el plugin no actualiza el nuevo conjunto de reglas de su dado.

He encontrado una solución en bruto: Antes de llamar al método de análisis en el lib discreto, i tirar el validador forma:

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

Ahora, cuando el método de validación es llamado por el lib discreto, todas las reglas y los mensajes se vuelven a crear incluyendo las entradas añadidas de forma dinámica.

Espero que esto ayude

Estoy utilizando MVC 4 y jQuery 1.8, tiene el siguiente fragmento de código es necesario para que jQuery para la validación del contenido de forma dinámica inyectada a través de Ajax, Jquery o en el DOM.

he hecho una función de modular que acepta el objeto Jquery del elemento recién añadido. Si ha clonado una nueva tabla con tblContacts Identificación usando jQuery en clic de un botón, a continuación, incluir la siguiente función en el 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 lo llaman así:

fnValidateDynamicContent("#tblContacts")

Tomando de la solución de Xhalent marcado como respuesta anterior, amplié en él 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 es todavía funciona igual que la solución de Xhalent anterior pero añade la capacidad de eliminar las reglas para los elementos que eliminar de la dom. Por lo tanto, cuando se quita elementos de la bóveda y quiere que esas reglas de validación eliminan también luego llamar a:

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

¿Por qué no usar las reglas funcionan directamente de doc validación de jQuery. De esta manera:

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

He encontrado @ escritura de código de Xhalent en mi código e iba a borrarlo porque no lo estaba usando, que me llevan a esta pregunta SO.

Este código es bastante limpio y sencillo:

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

A continuación, llamar a esta extensión de jQuery, sólo tiene que utilizar un selector para agarrar usted forma:

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

Viola!

Me trató la respuesta de viggity y al principio todo parecía funcionar. Pero después de un tiempo me di cuenta de que la validación se hace dolorosamente lento los más dinámica artículos que he ido añadiendo. La razón era que su solución no hace desatar los controladores de eventos, además de añadir otras nuevas cada vez. Así que si se agrega 5 artículos de la validación se ejecuta 6 veces en lugar de una sola vez. Para solucionar este problema, tiene que desenlazar los eventos, además de las llamadas REMOVEDATA.

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

En el caso de contenidos dinámicos necesita actualizar discreto validaciones que a continuación y comprobar si Form es válida mientras que la presentación.

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

He sido perder el tiempo con esto durante un tiempo, el desguace de soluciones y volver a intentarlo más tarde (cuando tuve algo de tiempo libre, aunque no lo crean).

No estoy seguro de si este comportamiento habría cambiado en las últimas versiones de jQuery (estamos usando 1.7.2) ya que este hilo se crea o se comentó pasado, pero me encontré con que .parseElement(inputElement) funciona bien cuando intento agregar creada dinámicamente elementos a una forma que ya tiene un validador cargado. Esto ya fue sugerido por @jamesfm (febrero 15 '11) en uno de los comentarios anteriores, pero se pasa por alto que las primeras veces que estaba trabajando en esto. Así que estoy añadiendo como una respuesta por separado para que sea más evidente y porque creo que es una buena solución y no requiere tanta 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 yo tengo la mía de trabajo:

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

En primer lugar, creo que la llamada debe ser a .validator, no valida, entonces usted necesita para pasar de la identificación de la forma

$.validator.unobtrusive.parse("#id");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top