1
votes

Validez qu'une seule entrée est remplie

J'ai le code suivant (jetez un œil à l'extrait de code) qui exécute un forEach sur un tableau pour voir s'il y a une entrée vide et ajouter une classe CSS. Il doit "marquer" si tous sont vides, ou si plus de deux entrées sont remplies.

Le processus que je veux faire, il devrait nécessiter exactement un seul des trois pour être rempli et les deux autres doivent être vides avant l'enregistrement.

 <form>
   <label for="optionA">Option A:</label>
   <input type="text" id="optionA" name="optionA"><br><br>
   <label for="optionB">Option B:</label>
   <input type="text" id="optionB" name="optionB"><br><br>
   <label for="optionC">Option C:</label>
   <input type="text" id="optionC" name="optionC"><br><br>
   <div id="save">Save</div>
 </form>

.alertField {
  border: 3px solid red;
}

#save {
  width: 200px;
  height: 20px;
  border: 1px solid green;
  cursor: pointer;
  text-align: center;
}
const save = document.getElementById("save");

save.addEventListener("click", function () {
  
  let fields = ["optionA", "optionB", "optionC"];

  fields.forEach(function (element, index, array) {
    if (document.getElementById(element).value == "") {
      document.getElementById(element).classList.add("alertField");
    } else {
      document.getElementById(element).classList.remove("alertField");
    }
  });
  
});
    Case A:
    
    optionA: filled
    optionB: empty
    optionC: empty
    
    Result Save: true.
    
    Case B:
    
    optionA: filled
    optionB: empty
    optionC: filled
    
    Result Save: false.


    Case C:
    
    optionA: empty
    optionB: empty
    optionC: empty
    
    Result Save: false.

Je me demande s'il existe une méthode de tableau pour faire cela.

PS: peut également jeter un oeil sur mon CodePen


0 commentaires

5 Réponses :


0
votes

Qu'en est-il simplement d'ajouter un compteur sur le nombre de champs ayant des valeurs, s'il n'y en a qu'un, continuez.

const save = document.getElementById("save");

save.addEventListener("click", function () {
  
  let fields = ["optionA", "optionB", "optionC"];
  let fieldsWithValue = 0;
  fields.forEach(function (element, index, array) {
    if (document.getElementById(element).value == "") {
      document.getElementById(element).classList.add("alertField");
    } else {
      document.getElementById(element).classList.remove("alertField");
      fieldsWithValue++;
    }
  });
  if (fieldsWithValue == 1) {
    //valid
  }
  else {
    //invalid
  }
});


1 commentaires

Il doit marquer les entrées, si elles sont toutes vides ou si plus de deux sont remplies.



0
votes

<form>
  <label for="optionA">Option A:</label>
  <input type="text" id="optionA" name="optionA"><br><br>
  <label for="optionB">Option B:</label>
  <input type="text" id="optionB" name="optionB"><br><br>
  <label for="optionC">Option C:</label>
  <input type="text" id="optionC" name="optionC"><br><br>
  <div id="save">Save</div>
</form>
.alertField {
  border: 3px solid red;
}

#save {
  width: 200px;
  height: 20px;
  border: 1px solid green;
  cursor: pointer;
  text-align: center;
}
const save = document.getElementById("save");

save.addEventListener("click", function() {

      let fields = ["optionA", "optionB", "optionC"];
      let inputs = [];
      let hasVal = [];
      fields.forEach(function(element, index, array) {
        let input = document.getElementById(element);
        input.classList.remove("alertField");
        inputs.push(input);
        if (input.value == "") {
          hasVal.push(false);
        } else {
          hasVal.push(true);
        }
      });

      let count = hasVal.filter(Boolean).length;

      if (!count) {
        inputs.forEach(input => input.classList.add("alertField"));
        }
        else if (count > 1) {
          inputs.forEach(input => {
            if (input.value) {
              input.classList.add("alertField");
            }
          })
        } else {
          // form.submit();
        }
      });


0 commentaires

2
votes

Si votre objectif est d'empêcher les utilisateurs de saisir du texte, ce que j'ai compris de votre question, vous pouvez écouter l'événement des champs que vous souhaitez restreindre et les deux champs s'allumeront en rouge, le dernier champ sera rouge uniquement s'il est vide, sinon la classe d'alerte sera supprimée.

Remarque : empêcher l'utilisateur de saisir du texte dans le champ de saisie n'est pas une bonne expérience utilisateur

 <form id="form">
   <label for="optionA">Option A:</label>
   <input type="text" id="optionA" name="optionA"><br><br>
   <label for="optionB">Option B:</label>
   <input type="text" id="optionB" name="optionB"><br><br>
   <label for="optionC">Option C:</label>
   <input type="text" id="optionC" name="optionC"><br><br>
   <div id="save">Save</div>
 </form>
.alertField {
  border: 3px solid red;
}

#save {
  width: 200px;
  height: 20px;
  border: 1px solid green;
  cursor: pointer;
  text-align: center;
}
const save = document.getElementById("save");
  const field1 = document.getElementById("optionA");
const form = document.getElementById("form");

form.addEventListener("keydown", e => {
  if(e.target.name=="optionC"||e.target.name=="optionA"||e.target.name=="optionB"){
    e.target.classList.remove("alertField")
  }
});

save.addEventListener("click", function () {
  
  let fields = ["optionA", "optionB", "optionC"];

  fields.forEach(function (element, index, array) {
    if (document.getElementById(element).value == "") {
      document.getElementById(element).classList.add("alertField");
    } else {
      document.getElementById(element).classList.remove("alertField");
    }
  });
  
});

Si le but de votre question est de basculer la classe d'alerte entre les champs lorsque le champ est vide, vous pouvez faire quelque chose comme ceci

 <form id="form">
   <label for="optionA">Option A:</label>
   <input type="text" id="optionA" name="optionA"><br><br>
   <label for="optionB">Option B:</label>
   <input type="text" id="optionB" name="optionB"><br><br>
   <label for="optionC">Option C:</label>
   <input type="text" id="optionC" name="optionC"><br><br>
   <div id="save">Save</div>
 </form>
.alertField {
  border: 3px solid red;
}

#save {
  width: 200px;
  height: 20px;
  border: 1px solid green;
  cursor: pointer;
  text-align: center;
}
  const save = document.getElementById("save");
  const field1 = document.getElementById("optionA");
  const form = document.getElementById("form");

form.addEventListener("keydown", e => {
 if(e.target.name=="optionA"||e.target.name=="optionB")
   e.preventDefault()
   if(e.target.name=="optionC"){
    e.target.classList.remove("alertField")
  }
});

save.addEventListener("click", function () {
  
  let fields = ["optionA", "optionB", "optionC"];

  fields.forEach(function (element, index, array) {
    if (document.getElementById(element).value == "") {
      document.getElementById(element).classList.add("alertField");
    } else {
      document.getElementById(element).classList.remove("alertField");
    }
  });
  
});


5 commentaires

@AndrewMyers eh bien c'est ce que OP veut, je suppose que c'est uniquement pour apprendre, mais pas un projet de la vie réelle


@AlwaysHelping Je comprends votre inquiétude, mais OP était précis dans ce qu'il veut, évidemment dans la vraie vie, vous ne pouvez pas empêcher les utilisateurs d'entrer, qui fait ça !!! c'est juste idiot.Mais je pense que c'est pour apprendre propose, si vous sentez que sa question n'est pas seulement, vous pouvez utiliser flag et je suis presque sûr qu'un modérateur fera l'appel nécessaire


Pas besoin de lettres MAJUSCULES, et j'ai mis à jour ma réponse, je pense que cette conversation n'est plus productive


@Voici mon vote positif pour vous. Tu as fais ce qu'il fallait faire. Bien sur vous.


Je pense que mon anglais n'est pas assez bon. Mais je veux juste alerter lorsque plusieurs entrées sont remplies. Je mettrai à jour ny post, car dans le vrai problème, j'ai plus de 10 entrées, et toute la validation se fait avec if-else conditionnel, et je veux "optimiser" en utilisant un tableau par exemple, en exécutant chaque entrée et en vérifiant est vide ou non, et en veillant également à ce qu’un seul soit rempli.



1
votes

Sven.hig a une bonne idée , mais voici comment procéder si vous n'essayez pas de vous arrêter entrée invalide.

Ce que je fais, c'est boucler deux fois les entrées. La première boucle consiste à obtenir un nombre d'entrées avec des données. La deuxième boucle ne se produit que s'il n'y a pas exactement une entrée avec des données.

Votre code d'origine a une boucle forEach , et c'est très bien. Vous pouvez obtenir un décompte avec cela, mais c'est le genre de chose Array.reduce () a été fait pour. (J'admets cependant qu'il est difficile de me rappeler comment utiliser réduire - je dois consulter la documentation presque à chaque fois.)

Le code ci-dessous devrait répondre à vos exigences . Si aucune valeur n'est fournie, tous les champs seront mis en surbrillance. Si plusieurs valeurs reçoivent une valeur, seuls les champs contenant des valeurs seront mis en surbrillance.

<form>
   <label for="optionA">Option A:</label>
   <input type="text" id="optionA" name="optionA"><br><br>
   <label for="optionB">Option B:</label>
   <input type="text" id="optionB" name="optionB"><br><br>
   <label for="optionC">Option C:</label>
   <input type="text" id="optionC" name="optionC"><br><br>
   <div id="save">Save</div>
 </form>
.alertField {
  border: 3px solid red;
}

#save {
  width: 200px;
  height: 20px;
  border: 1px solid green;
  cursor: pointer;
  text-align: center;
}
const save = document.getElementById("save");

save.addEventListener("click", function () {
  
  let fields = ["optionA", "optionB", "optionC"];
  
  let counter = fields.reduce(function (count, element) {
    if (document.getElementById(element).value === "") {
      return count;
    }
    return count + 1;
  }, 0);
  
  if (counter < 1) {
    fields.forEach(function (element) {
      document.getElementById(element).classList.add("alertField");
    });
  } else if (counter > 1) {
    fields.forEach(function (element) {
      if (document.getElementById(element).value !== "") {
        document.getElementById(element).classList.add("alertField");
      }
    });
  }
  
});


1 commentaires

Votre exemple m'a permis de connaître les autres méthodes de tableau existantes que je peux utiliser avec JS. Tout d'abord, j'ai utilisé array.every pour savoir si toutes les entrées sont vides. Ensuite, j'ai utilisé une contidion if-else où les travaux dépendent du résultat array.every . Dans les conditions if-else , j'ai utilisé les méthodes forEach et aussi array.push . Au résultat, j'ai obtenu ce que je veux, et remplissez les trois cas que vous pouvez consulter sur mon message de problème.



0
votes

Objectif: le processus que je souhaite effectuer doit nécessiter exactement un seul des trois à remplir et les deux autres à être vides avant l'enregistrement.

<form>

  <p>The following form has three input type text that receives data.</p>
  
  <label for="optionA">Option A:</label>
  <input type="text" id="optionA" name="optionA"><br><br>
  <label for="optionB">Option B:</label>
  <input type="text" id="optionB" name="optionB"><br><br>
  <label for="optionC">Option C:</label>
  <input type="text" id="optionC" name="optionC"><br><br>
  
  <p>The following button "Save Only One" works as a validation, where only one input has to be filled</p>
  
  <input id="saveOne" class="save" value="Save Only One" type="sumbit"/>
  
  <p>It is used with Array methods instead of if-else conditional, because it could be a case when exits more than one inputs text.</p>
  
</form>

body {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #bdc3c7;
  height: 100vh;
}

form {
  background-color: #f39c12;
  width: 400px;
  padding: 20px;
  border: 2px solid #c0392b;
}

.alertField {
  border: 4px solid #c0392b;
}

input {
  border-radius: 4px;
  width: 100%;
  height: 20px;
}

.save {
  display: block;
  border: 1px solid #2980b9;
  cursor: pointer;
  text-align: center;
  background-color: #3498db;
  color: #ecf0f1;
  font-weight: bold;
  margin-top: 15px;
}
const save = document.getElementById("save");

 // Next method require only one input be filled.

saveOne.addEventListener("click", function (e) {
  e.preventDefault();

  let fields = ["optionA", "optionB", "optionC"];
  let fieldsFilled = [];
  let count = 0;

  var allEmpty = fields.every(function (element) {
    return document.getElementById(element).value == "";
  });

  if (allEmpty) {
    fields.forEach(function (element) {
      if (document.getElementById(element).value == "") {
        document.getElementById(element).classList.add("alertField");
      }
    });
  } else {
    fields.forEach(function (element, index, array) {
      if (document.getElementById(element).value != "") {
        fieldsFilled.push(element);
        document.getElementById(element).classList.remove("alertField");
      } else {
        document.getElementById(element).classList.remove("alertField");
      }
    });

    fieldsFilled.forEach(function (element, index, array) {
      if (fieldsFilled.length > 1) {
        document.getElementById(element).classList.add("alertField");
        count = count + 1;
      }
    });
  }
});
Case A:

optionA: filled
optionB: empty
optionC: empty

Result Save: true.

Case B:

optionA: filled
optionB: empty
optionC: filled

Result Save: false.

Case C:

optionA: empty
optionB: empty
optionC: empty

Result Save: false.

Qu'avez-vous appris sur ce problème?

Les connaissances sur les validations d'application avec les méthodes array .

Pourquoi le problème s'est-il produit?

Situation de travail où la table dynamique génère beaucoup d'entrées et elle a été résolue à ce moment-là avec beaucoup de conditionnel if-else .

C'est pourquoi Je me demandais que cela pourrait être résolu aussi d'une autre manière, j'ai pensé dans les tableaux parce que la table dynamique génère des identifiants par entrée.


0 commentaires