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
3 Réponses :
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(); }
});
});
Remarques:
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
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.
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();
}
});
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).
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
focusau champ de saisie. Dans le rappel, si la propriétévaluede l'entrée est vraie, vous invoquez de force la méthodeblur ().@Terry Eh bien non, ce n'est pas le cas. Parce que l'entrée ne peut pas être effacée facilement actuellement.