Je fais une simple validation de formulaire ici et je suis resté bloqué sur un problème très basique. J'ai 5 paires de champs pour le nom et l'entrée (pour une inscription au dîner). L'utilisateur peut entrer 1-5 paires, mais une entrée doit être sélectionnée si un nom est présent. Code:
<form>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
<input type="submit" value="Submit">
</form>
// Prevent form submit if any entrees are missing
$('form').submit(function(e){
e.preventDefault();
// Cycle through each Attendee Name
$('[name="atendeename[]"]', this).each(function(index, el){
// If there is a value
if ($(el).val()) {
// Find adjacent entree input
var entree = $(el).next('input');
// If entree is empty, don't submit form
if ( ! entree.val()) {
alert('Please select an entree');
entree.focus();
return false;
}
}
});
$('form').unbind('submit').submit();
});
Le message d'erreur fonctionne, mais il envoie le formulaire à chaque fois. Je sais qu'il y a quelque chose qui cloche dans cette ligne:
$('form').unbind('submit').submit();
... mais je ne suis pas sûr de ce que je dois faire.
La solution la plus simple consiste simplement à not appeler e.preventDefault()
sauf si la validation échoue. Déplacez cette ligne à l'intérieur de l'instruction if
interne et supprimez la dernière ligne de la fonction avec la fonction .unbind().submit()
.
Utilisez la fonction native element.submit()
pour contourner le preventDefault dans le gestionnaire jQuery et notez que votre instruction return renvoie uniquement à partir de chaque boucle, elle ne renvoie pas à partir du gestionnaire d'événements.
$('form').submit(function(e){
e.preventDefault();
var valid = true;
$('[name="atendeename[]"]', this).each(function(index, el){
if ( $(el).val() ) {
var entree = $(el).next('input');
if ( ! entree.val()) {
entree.focus();
valid = false;
}
}
});
if (valid) this.submit();
});
Le problème est que, même si vous voyez l'erreur, votre return false
Affecte le rappel de la méthode .each()
... donc, même s'il y a une erreur, vous atteignez la ligne.
$('form').unbind('submit').submit();
et le formulaire est soumis.
Vous devez créer une variable, validated
, par exemple, et la définir sur true. Ensuite, dans le rappel, au lieu de return false
, Définissez validated = false
.
Finalement...
if (validated) $('form').unbind('submit').submit();
De cette façon, le formulaire ne sera envoyé que s'il n'y a pas d'erreur.
$('form').submit(function(e){
var submitAllow = true;
// Cycle through each Attendee Name
$('[name="atendeename[]"]', this).each(function(index, el){
// If there is a value
if ($(el).val()) {
// Find adjacent entree input
var entree = $(el).next('input');
// If entree is empty, don't submit form
if ( ! entree.val()) {
alert('Please select an entree');
entree.focus();
submitAllow = false;
return false;
}
}
});
return submitAllow;
});
En fait, cela semble être le bon moyen:
$('form').submit(function(e){
//prevent default
e.preventDefault();
//do something here
//continue submitting
e.currentTarget.submit();
});
Désolé pour le retard, mais je vais essayer de rendre la forme parfaite :)
Je vais ajouter les étapes de validation du compte et vérifier chaque fois pas .val()
. Vérifier .length
, parce que je pense que c'est un meilleur modèle dans votre cas. Bien sûr, supprimez la fonction unbind
.
Bien sûr le code source:
// Prevent form submit if any entrees are missing
$('form').submit(function(e){
e.preventDefault();
var formIsValid = true;
// Count validation steps
var validationLoop = 0;
// Cycle through each Attendee Name
$('[name="atendeename[]"]', this).each(function(index, el){
// If there is a value
if ($(el).val().length > 0) {
validationLoop++;
// Find adjacent entree input
var entree = $(el).next('input');
var entreeValue = entree.val();
// If entree is empty, don't submit form
if (entreeValue.length === 0) {
alert('Please select an entree');
entree.focus();
formIsValid = false;
return false;
}
}
});
if (formIsValid && validationLoop > 0) {
alert("Correct Form");
return true;
} else {
return false;
}
});
Pourquoi ne pas lier l'événement bouton de soumission au formulaire lui-même? il serait vraiment beaucoup plus facile et plus sûr de lier les boutons que le formulaire lui-même, car le formulaire sera généralement soumis à moins que vous n'utilisiez preventDefault()
$("#btn-submit").on("click", function (e) {
var submitAllow = true;
$('[name="atendeename[]"]', this).each(function(index, el){
// If there is a value
if ($(el).val()) {
// Find adjacent entree input
var entree = $(el).next('input');
// If entree is empty, don't submit form
if ( ! entree.val()) {
alert('Please select an entree');
entree.focus();
submitAllow = false;
return false;
}
}
});
if (submitAllow) {
$("#form-attendee").submit();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form-attendee">
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
Name: <input name="atendeename[]">
Entree: <input name="entree[]"><br>
<button type="button" id="btn-submit">Submit<button>
</form>