2
votes

Auto Sélection du champ de saisie suivant et retour

Une fois saisi, un utilisateur ne peut pas revenir en arrière pour modifier son entrée.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="code" action="*" method="post" autocomplete="off">
  <input type="text" name="code" maxlength="1" autocomplete="off" class="a">
  <input type="text" name="code" maxlength="1" autocomplete="off" class="b">
  <input type="text" name="code" maxlength="1" autocomplete="off" class="c">
  <span>—</span>
  <input type="text" name="code" maxlength="1" autocomplete="off" class="d">
  <input type="text" name="code" maxlength="1" autocomplete="off" class="e">
  <input type="text" name="code" maxlength="1" autocomplete="off" class="f last">
</form>
input {
  width: 20px;
  text-align: center;
}
$("form").on("keyup change paste", function(e) {
  e.preventDefault();

  var a = $(this).find("input[type='text'].a");
  var b = $(this).find("input[type='text'].b");
  var c = $(this).find("input[type='text'].c");
  var d = $(this).find("input[type='text'].d");
  var e = $(this).find("input[type='text'].e");
  var f = $(this).find("input[type='text'].f");

  a.val(a.val().replace(/[^0-9]/g, ""));
  b.val(b.val().replace(/[^0-9]/g, ""));
  c.val(c.val().replace(/[^0-9]/g, ""));
  d.val(d.val().replace(/[^0-9]/g, ""));
  e.val(e.val().replace(/[^0-9]/g, ""));
  f.val(f.val().replace(/[^0-9]/g, ""));

  if (a.val().length == a.attr('maxlength')) {
    a.next("input").focus();
  }
  if (b.val().length == a.attr('maxlength')) {
    b.next("input").focus();
  }
  if (c.val().length == a.attr('maxlength')) {
    c.next().next("input").focus();
  }
  if (d.val().length == a.attr('maxlength')) {
    d.next("input").focus();
  }
  if (e.val().length == a.attr('maxlength')) {
    e.next("input").focus();
  }
  if (f.val().length == a.attr('maxlength')) {
    f.next("input").focus();
  }
});

Comment cela peut-il être fait?

Et y a-t-il une approche plus élégante de la mienne ci-dessus?


En direct: jsFiddle


4 commentaires

Pour être sûr de bien le comprendre, vous souhaitez interdire à l'utilisateur de modifier un numéro qu'il a inséré?


@ GrégoryNEUT Une fois que vous êtes à la fin, et que vous voulez effacer un numéro. Actuellement, vous devez entrer dans chaque champ et les modifier de cette façon.


Cela ne semble pas être une manière très conviviale de faire les choses, mais si vous voulez vraiment empêcher les utilisateurs de modifier un champ de saisie rempli, liez simplement l'événement focus au champ de saisie. Dans le rappel, si la propriété value de l'entrée est vraie, vous invoquez de force la méthode blur () .


@Terry Eh bien non, ce n'est pas le cas. Parce que l'entrée ne peut pas être effacée facilement actuellement.


3 Réponses :


2
votes

Chaque fois que vous trouvez du code très répétitif, pensez toujours à LOOP.

Ce qui suit permettra à l'utilisateur de modifier ses valeurs. Cela réduit également considérablement votre code.

$('form').on('input', e => {
    var letters = ['a', 'b', 'c', 'd', 'e', 'f'];
    letters.forEach(letter => {
        let field = $(e.target);
        field.val(field.val().replace(/[^0-9]/g, ''));
        if(field.val().length == field.attr('maxlength')) { field.nextAll('input').first().focus(); }
    });
});

Fiddle a >.

Remarques:

  • Écoutez l'événement d'entrée; il présente l’avantage de couvrir tous les événements que vous écoutiez et, surtout, de déclencher après l’appui sur une touche (ce qui signifie que vous pouvez être sûr de saisir la dernière valeur complète du champ)
  • éviter les codes répétitifs; la boucle nous permet d'écrire la logique métier une fois plutôt que de manière répétée
  • il n'est pas nécessaire d'empêcher l'action par défaut de l'événement
  • en utilisant nextAll ('input'). first () , nous pouvons être sûrs d'obtenir la prochaine entrée , que ce soit le frère suivant ou, comme c'est le cas cas avec la troisième entrée, séparée par un autre type d'élément


6 commentaires

Fonctionne très bien sur l'entrée initiale. Cependant, si un utilisateur souhaite modifier sa saisie en effaçant du champ f vers le champ a , cela peut-il être fait?


"effacement du champ f vers le champ a" - je ne sais pas ce que vous voulez dire


J'ai donc entré 123-123. Je suis maintenant à input.f . J'efface input.f . Et le focus devrait revenir à input.e .


OK, c'est différent de votre question actuelle. Et je ne vois aucun sens à l'interface utilisateur pour expliquer pourquoi cela devrait se produire, mais ce n'est que mon avis. Pourquoi ne pas essayer vous-même.


Veuillez créer un extrait de code stackoverflow au lieu d'un Fiddle, c'est beaucoup plus facile à essayer


@ GrégoryNEUT - cela n'a de sens que si vous incluez également le HTML, ce que ma réponse ne fait pas. La question portait sur JS, et sans le HTML, le JS n'a pas de capacité de démonstration.



0
votes

Mon idée serait de me concentrer ensuite et de faire une boucle en arrivant au dernier. Remplacez le nombre en cas de nouvelle entrée.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="code" action="*" method="post" autocomplete="off">
</form>
input {
  width: 20px;
  text-align: center;
}
// init the html
const nbInput = 6;

let html = '';

for (let i = 0; i < nbInput; i += 1) {
  html += `<input type="text" name="code" maxlength="1" autocomplete="off" number="${i}">`;
}

$('form').html(html);

$('form input').on('keypress', function(e) {
  e.preventDefault();
  
  // Ignore bad values
  if (/^[^0-9]$/g.test(String.fromCharCode(e.which))) {
    return;
  }

  // Replace the actual value with the keypressed one
  $(this).val(String.fromCharCode(e.which));

  // Reset & focus next
  if ($(this).val() !== '' && Number($(this).attr('number')) < (nbInput - 1)) {
    $(`input[number=${Number($(this).attr('number')) + 1}]`).focus();
  } else {
    // Focus the first item when we finished
    $('input[number="0"]').focus();
  }
});


0 commentaires

0
votes

Effacer les entrées sur le focus le ferait. (Je n'utilise pas beaucoup jQuery, donc excuses si j'ai une syntaxe incorrecte.)

$("form").focus(function() {

    var a = $(this).find("input[type='text'].a")
    var b = $(this).find("input[type='text'].b") // ...etc  

    a.val("");
    b.val(""); // ...etc
});

Cela dit, Utkanos a raison à 100% qu'une boucle est le bon moyen de gérer les deux problèmes ( avancer automatiquement et autoriser les modifications).


0 commentaires