Je suis l'aide de l'excellent jQuery Valider Plugin pour valider certaines formes. Sur un formulaire, j'ai besoin de s'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 le partager. Veuillez suggérer d'éventuelles améliorations que vous pouvez penser.
Ne trouvant pas de moyen intégré pour ce faire, j'ai cherché et trouvé Rebecca Murphey personnalisée de la méthode de validation, qui a été très utile.
J'ai amélioré ce, de trois façons:
- Pour vous permettre de passer un sélecteur pour le groupe de champs
- Pour vous permettre de spécifier combien de ce groupe doivent être remplis pour que la validation de passer
- Pour afficher toutes les entrées dans le groupe en tant que passage de validation dès que l'un d'entre eux passe la validation. (Voir shout-out à Nick Craver à la fin.)
Ainsi, vous pouvez dire "au moins X entrées qui correspondent sélecteur de Y doit être rempli."
Le résultat final, avec des balises comme ceci:
<input class="productinfo" name="partnumber">
<input class="productinfo" name="description">
...est un ensemble de règles comme ceci:
// 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ément #3 suppose que vous êtes en train d'ajouter une classe d' .checked
pour vos messages d'erreur lors de la validation. Vous pouvez le faire comme suit, comme démontré ici.
success: function(label) {
label.html(" ").addClass("checked");
}
Comme dans la démo ci-dessus, j'utilise le CSS pour donner à chaque span.error
X image comme arrière-plan, à moins qu'il a la classe .checked
, auquel cas il devient une marque de contrôle de l'image.
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!
Shout out
Maintenant, pour que shout-out à l'origine, mon code juste aveuglément caché les messages d'erreur sur les autres champs correspondants au lieu de re-valider, ce qui signifie que s'il y avait un autre problème (comme seuls les chiffres sont autorisés et que vous avez entré lettres"), il a caché jusqu'à ce que l'utilisateur a essayé de se soumettre. Ce était parce que je ne sais pas comment faire pour éviter la boucle de rétroaction mentionné dans les commentaires ci-dessus. Je savais qu'il y doit y avoir un moyen, donc j'ai posé une question, et Nick Craver m'a éclairé. Merci, Nick!
Question Résolu
C'était à l'origine un "permettez-moi de partager cela et voir si quelqu'un peut suggérer des améliorations" genre de question. Alors que j'avais toujours les bienvenus commentaires, je pense qu'il est assez complète à ce point. (Il pourrait être plus court, mais je veux qu'il soit facile à lire et pas nécessairement concis.) Donc, juste profiter!
Mise à jour - qui fait maintenant partie de jQuery de Validation
Cela a été officiellement ajouté à jQuery de Validation sur 4/3/2012.