Question

Je travaille avec ASP.Net MVC3, la manière plus facile à utiliser la validation client serait permettant au jquery.validate.unobtrusive. Tout fonctionne très bien, pour des choses qui est juste du serveur.

Mais quand j'essaie d'injecter de nouvelles « intrants » avec javascript, et je savais que je dois appeler $.validator.unobtrusive.parse() pour reconsolider les validations. Mais encore, tous ces champs injectés dynamiques ne fonctionnent pas.

Pire encore, j'essaie de lier manuellement à l'aide jquery.validate et il ne fonctionne pas non plus. Toute pensée?

Était-ce utile?

La solution

J'ai créé une extension pour la bibliothèque jquery.validate.unobtrusive qui a résolu ce problème pour ma situation -. Il pourrait être d'intérêt

http://xhalent.wordpress.com/2011/ 01/24 / application-dynamique à-validation discret contenu /

Autres conseils

J'ai essayé l'approche de Xhalent, mais malheureusement, il ne fonctionnait pas pour moi. L'approche de Robin a fait le travail et ne fonctionnait pas. Il fonctionnait très bien pour les éléments ajoutés dynamiquement, mais si vous avez essayé d'utiliser JQuery pour supprimer tous les attributs de validation et de travées du DOM, la bibliothèque de validation serait toujours essayer de les valider.

Toutefois, si vous supprimez les données « unobtrusiveValidation » du formulaire en plus de « validationData », cela a fonctionné comme un charme pour ajouter dynamiquement et supprimer des éléments que vous souhaitez contrôler ou non Validé.

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

En fait, je vraiment la simplicité de @viggity solution @Robins, alors je l'ai transformé en un petit plug-in rapide:

(function ($) {

    $.fn.updateValidation = function () {
        var $this = $(this);
        var form = $this.closest("form")
            .removeData("validator")
            .removeData("unobtrusiveValidation");

        $.validator.unobtrusive.parse(form);

        return $this;
    };
})(jQuery);

Exemple d'utilisation:

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

Je vais avoir le même problème. Je l'ai découvert est pas possible d'appeler .validator.unobtrusive.parse $ () sur le même formulaire deux fois. Lors du chargement de la forme au départ du serveur le formulaire est automatiquement analysé par la bibliothèque discrète. Lorsque vous ajoutez un élément d'entrée dynamique à la forme et appelez .validator.unobtrusive.parse $ () à nouveau, il ne fonctionnera pas. La même chose vaut pour parseElement ().

Le lib discret appelle la méthode de validation de la validation jquery plug-in pour définir toutes les règles et les messages. Le problème est, lorsqu'il est appelé à nouveau, le plug-in ne met pas à jour la nouvelle série de règles de son donné.

J'ai trouvé une solution brute: Avant d'appeler la méthode d'analyse sur le unobstrusive lib, je jette la forme validateur:

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

, lorsque la méthode de validation est appelée par le lib discret, toutes les règles et les messages sont recréés, y compris les entrées ajoutées dynamiquement.

Hope this helps

J'utilise MVC 4 et JQuery 1.8, ressemble le morceau de code suivant est nécessaire pour permettre la validation du contenu Jquery injecté dynamiquement via Ajax ou Jquery dans le DOM.

I ai fait une fonction modulaire qui accepte l'objet Jquery de l'élément nouvellement ajouté. Si vous avez cloné une nouvelle table avec identifiant tblContacts en utilisant Jquery sur clic d'un bouton, puis inclure ci-dessous la fonction dans votre fichier 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.
}

et l'appeler comme ceci:

fnValidateDynamicContent("#tblContacts")

La prise de la solution de Xhalent marqué comme réponse ci-dessus, j'Elargi de un peu.

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

Donc, fondamentalement, il fonctionne toujours le même que la solution de Xhalent ci-dessus, mais j'ai ajouté la possibilité de supprimer des règles pour les éléments que vous supprimez du dom. Donc, lorsque vous supprimez des éléments du Dom et vous voulez que ces règles de validation également supprimées puis appelez:

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

Pourquoi ne pas utiliser la fonction de règles directement à partir de la validation jquery doc. Comme ceci:

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

J'ai trouvé @ script code de Xhalent dans mon code et je vais le supprimer parce que je ne l'utilise pas, ce qui me conduit à cette question SO.

Ce code est assez propre et 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();
}

Ensuite, pour appeler cette extension jQuery, il suffit d'utiliser un sélecteur pour vous saisir de forme:

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

Viola!

J'ai essayé la réponse de viggity et au début, tout semblait fonctionner. Mais après un certain temps, j'ai remarqué que la validation devient douloureusement lent les éléments plus dynamiquement je. La raison en était que sa solution ne pas délier les gestionnaires d'événements, mais ajouter de nouveaux à chaque fois. Donc, si vous ajoutez 5 éléments de la validation est exécutée 6 fois au lieu de seulement une fois. Pour corriger cela, vous devez délier les événements en plus des appels 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 cas de contenu dynamique, vous devez mettre à jour Validations comme ci-dessous discrets et vérifier si Form est valide lors de la soumission.

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

Je suis bidouiller avec pendant un certain temps, des solutions déchirage et d'essayer à nouveau plus tard (quand j'avais un peu de temps, croyez-le ou non).

Je ne sais pas si ce comportement aurait changé dans les versions les plus récentes de jquery (nous utilisons 1.7.2) car ce fil a été créé ou commenté dernier, mais je trouve que .parseElement(inputElement) fonctionne très bien lorsque je tente d'ajouter dynamiquement créé des éléments à une forme qui a déjà un validateur chargé. Cela a déjà été suggéré par @jamesfm (15 février '11) dans l'un des commentaires ci-dessus, mais je négligé ce les premières fois où je travaillais à ce sujet. Donc, je l'ajouter comme une réponse distincte pour le rendre plus évident et parce que je pense qu'il est une bonne solution et ne nécessite pas de frais généraux. Il pourrait ne pas être pertinent pour toutes les questions soulevées dans les réponses suivantes, mais je pense que ce serait une solution à la question initiale. Voici comment je suis arrivé travail à moi:

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

Tout d'abord, je pense que l'appel devrait être de .validator, ne validera pas passer alors vous devez l'ID du formulaire

$.validator.unobtrusive.parse("#id");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top