J'utilise l'excellent plug-in jQuery Validate pour valider certains formulaires. Sur un formulaire, je dois m'assurer que l'utilisateur remplit au moins l'un d'un groupe de champs. Je pense que j'ai une assez bonne solution et je voulais la partager. Veuillez suggérer les améliorations auxquelles vous pourriez penser.
Ne trouvant aucun moyen intégré de le faire, j'ai recherché et trouvé la méthode de validation personnalisée de Rebecca Murphey , ce qui était très utile.
J'ai amélioré cela de trois manières:
- Pour vous laisser passer un sélecteur pour le groupe de champs
- Pour vous permettre de spécifier combien de ce groupe doit être rempli pour que la validation réussisse
- Pour afficher toutes les entrées du groupe comme ayant réussi la validation dès que l'une d'elles réussit la validation. (Voir le cri à Nick Craver à la fin.)
Vous pouvez donc dire "au moins X entrées correspondant au sélecteur Y doivent être renseignées".
Le résultat final, avec un balisage comme celui-ci:
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
... est un groupe de règles comme celui-ci:
// Both these inputs input will validate if
// at least 1 input with class 'productinfo' is filled
partnumber: {
require_from_group: [1,".productinfo"]
}
description: {
require_from_group: [1,".productinfo"]
}
L'élément n ° 3 suppose que vous ajoutez une classe de .checked
à vos messages d'erreur après une validation réussie. Vous pouvez le faire comme suit, comme illustré ici .
success: function(label) {
label.html(" ").addClass("checked");
}
Comme dans la démo liée ci-dessus, j'utilise CSS pour donner à chaque span.error
image X comme arrière-plan, à moins qu'elle n'ait la classe .checked
, auquel cas elle obtient une image de coche.
Voici mon code pour l'instant:
jQuery.validator.addMethod("require_from_group", function(value, element, options) {
var numberRequired = options[0];
var selector = options[1];
//Look for our selector within the parent form
var validOrNot = $(selector, element.form).filter(function() {
// Each field is kept if it has a value
return $(this).val();
// Set to true if there are enough, else to false
}).length >= numberRequired;
// The elegent part - this element needs to check the others that match the
// selector, but we don't want to set off a feedback loop where each element
// has to check each other element. It would be like:
// Element 1: "I might be valid if you're valid. Are you?"
// Element 2: "Let's see. I might be valid if YOU'RE valid. Are you?"
// Element 1: "Let's see. I might be valid if YOU'RE valid. Are you?"
// ...etc, until we get a "too much recursion" error.
//
// So instead we
// 1) Flag all matching elements as 'currently being validated'
// using jQuery's .data()
// 2) Re-run validation on each of them. Since the others are now
// flagged as being in the process, they will skip this section,
// and therefore won't turn around and validate everything else
// 3) Once that's done, we remove the 'currently being validated' flag
// from all the elements
if(!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
// .valid() means "validate using all applicable rules" (which
// includes this one)
fields.valid();
fields.data('being_validated', false);
}
return validOrNot;
// {0} below is the 0th item in the options field
}, jQuery.format("Please fill out at least {0} of these fields."));
Hourra!
Hurler
Maintenant, pour ce cri - à l'origine, mon code cachait aveuglément les messages d'erreur sur les autres champs correspondants au lieu de les revalider, ce qui signifiait que s'il y avait un autre problème (comme `` seuls les nombres sont autorisés et vous avez entré des lettres '') , il a été masqué jusqu'à ce que l'utilisateur tente de soumettre. C'était parce que je ne savais pas comment éviter la boucle de rétroaction mentionnée dans les commentaires ci-dessus. Je savais qu'il devait y avoir un moyen, alors j'ai posé une question et Nick Craver m'a éclairé. Merci Nick!
Question résolue
C'était à l'origine une question «laissez-moi partager ceci et voir si quelqu'un peut suggérer des améliorations». Bien que j'apprécie toujours les commentaires, je pense qu'ils sont assez complets à ce stade. (Cela pourrait être plus court, mais je veux que ce soit facile à lire et pas nécessairement concis.) Alors profitez-en!
Mise à jour - fait désormais partie de jQuery Validation
Cela a été officiellement ajouté à jQuery Validation le 4/3/2012.