Comment focaliser l'entrée suivante une fois que l'entrée précédente a atteint sa valeur maxlength?
a: <input type="text" maxlength="5" />
b: <input type="text" maxlength="5" />
c: <input type="text" maxlength="5" />
Si un utilisateur colle un texte supérieur à maxlength, il devrait idéalement déborder sur la prochaine entrée.
jsFiddle:http://jsfiddle.net/4m5fg/1/
Je tiens à souligner que je ne pas souhaite utiliser un plug-in, car je préférerais de beaucoup apprendre la logique derrière cela, plutôt que d'utiliser quelque chose qui existe déjà. Merci de votre compréhension.
JQuery n'est pas utilisé et est une implémentation très propre:
<div class="container">
a: <input type="text" maxlength="5" />
b: <input type="text" maxlength="5" />
c: <input type="text" maxlength="5" />
</div>
..
var container = document.getElementsByClassName("container")[0];
container.onkeyup = function(e) {
var target = e.srcElement || e.target;
var maxLength = parseInt(target.attributes["maxlength"].value, 10);
var myLength = target.value.length;
if (myLength >= maxLength) {
var next = target;
while (next = next.nextElementSibling) {
if (next == null)
break;
if (next.tagName.toLowerCase() === "input") {
next.focus();
break;
}
}
}
// Move to previous field if empty (user pressed backspace)
else if (myLength === 0) {
var previous = target;
while (previous = previous.previousElementSibling) {
if (previous == null)
break;
if (previous.tagName.toLowerCase() === "input") {
previous.focus();
break;
}
}
}
}
Vous pouvez surveiller les entrées dans les champs et tester leur valeur:
$("input").bind("input", function() {
var $this = $(this);
setTimeout(function() {
if ( $this.val().length >= parseInt($this.attr("maxlength"),10) )
$this.next("input").focus();
},0);
});
La setTimeout
est là pour assurer que le code ne sera exécuté que après que la saisie soit terminée et la valeur mise à jour. La liaison input
garantit que la plupart des types d’entrée déclenchent l’événement, y compris les appuis sur les touches, le copier/coller (même à partir de la souris) et le glisser-déposer (bien que dans ce cas, ce dernier ne fonctionnera pas, car la bave).
Note: sur certains navigateurs plus anciens, vous devrez peut-être également lier propertychange
.
Si un utilisateur colle un texte supérieur à maxlength, il devrait idéalement déborder sur la prochaine entrée.
Pour ce faire, vous devrez peut-être supprimer l'attribut maxlength
à l'aide de JavaScript (pour pouvoir capturer toute l'entrée) et implémenter cette fonctionnalité vous-même. J'ai fait un petit exemple , parties pertinentes ci-dessous:
$("input").each(function() {
var $this = $(this);
$(this).data("maxlength", $this.prop("maxlength"));
$(this).removeAttr("maxlength");
})
Cela supprime l'attribut, mais l'enregistre dans data
, afin que vous puissiez y accéder plus tard.
function spill($this, val) {
var maxlength = $this.data("maxlength");
if ( val.length >= maxlength ) {
$this.val(val.substring(0, maxlength));
var next = $this.next("input").focus();
spill(next, val.substring(maxlength));
}
else
$this.val(val);
}
Ici, la logique de longueur maximale est réintroduite dans JavaScript, ainsi que d'obtenir la partie "rejetée" et de l'utiliser dans un appel récursif à spill
. S'il n'y a pas d'élément suivant, l'appel à data
renverra undefined
et la boucle s'arrêtera, de sorte que l'entrée sera tronquée dans le dernier champ.
Vous pouvez utiliser du JavaScript simple:
Voir DEMO .
Vérifiez la longueur des caractères avec el.value.length
. Si elle est égale à la valeur maximale, passez au champ suivant en utilisant focus()
. Liez cette fonction à l'événement keyup avec onkeyup
pour qu'elle soit activée à chaque fois que l'utilisateur a saisi un caractère.
var a = document.getElementById("a"),
b = document.getElementById("b"),
c = document.getElementById("c");
a.onkeyup = function() {
if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
b.focus();
}
}
b.onkeyup = function() {
if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
c.focus();
}
}
si vous avez plusieurs champs, vous pouvez faire quelque chose comme ceci.
fondamentalement sur keyup
, obtenez la longueur de l'entrée, puis comparez-la à la longueur maximale, si elle correspond, puis focus
au champ d'entrée suivant.
http://jsfiddle.net/btevfik/DVxDA/
$(document).ready(function(){
$('input').keyup(function(){
if(this.value.length==$(this).attr("maxlength")){
$(this).next().focus();
}
});
});
Si vous vous concentrez sur la création d'un type de saisie de numéro de carte (débit/crédit). Nettoyez ensuite une version jQuery facile à gérer comme suit:
/*..............................................................................................
* jQuery function for Credit card number input group
......................................................................................................*/
// make container label of input groups, responsible
$('.card-box').on('focus', function(e){
$(this).parent().addClass('focus-form-control');
});
$('.card-box').on('blur', function(e){
$(this).parent().removeClass('focus-form-control');
});
$('.card-box-1').on('keyup', function(e){
e.preventDefault();
var max_length = parseInt($(this).attr('maxLength'));
var _length = parseInt($(this).val().length);
if(_length >= max_length) {
$('.card-box-2').focus().removeAttr('readonly');
$(this).attr('readonly', 'readonly');
}
if(_length <= 0){
return;
}
});
$('.card-box-2').on('keyup', function(e){
e.preventDefault();
var max_length = parseInt($(this).attr('maxLength'));
var _length = parseInt($(this).val().length);
if(_length >= max_length) {
$('.card-box-3').focus().removeAttr('readonly');
$(this).attr('readonly', 'readonly');
}
if(_length <= 0){
$('.card-box-1').focus().removeAttr('readonly');
$(this).attr('readonly', 'readonly');
}
});
$('.card-box-3').on('keyup', function(e){
e.preventDefault();
var max_length = parseInt($(this).attr('maxLength'));
var _length = parseInt($(this).val().length);
if(_length >= max_length) {
$('.card-box-4').focus().removeAttr('readonly');
$(this).attr('readonly', 'readonly');
}
if(_length <= 0){
$('.card-box-2').focus().removeAttr('readonly');
$(this).attr('readonly', 'readonly');
}
});
$('.card-box-4').on('keyup', function(e){
e.preventDefault();
var max_length = parseInt($(this).attr('maxLength'));
var _length = parseInt($(this).val().length);
if(_length >= max_length) {
return;
}
if(_length <= 0){
$('.card-box-3').focus().removeAttr('readonly');
$(this).attr('readonly', 'readonly');
}
});
/*..............................................................................................
* End jQuery function for Credit card number input group
......................................................................................................*/
/* Hide HTML5 Up and Down arrows. */
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none; margin: 0;
}
input[type="number"] { -moz-appearance: textfield; }
.card-box {
width: 20%; display: inline-block; height: 100%; border: none;
}
.focus-form-control {
border-color: #66afe9; outline: 0;-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="form-control" style="padding: 0; max-width: 300px; ">
<input class="card-box card-box-1" type="number" id="CreditCard_CardNumber1" required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;"/>
<input class="card-box card-box-2" type="number" id="CreditCard_CardNumber2" readonly required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;" />
<input class="card-box card-box-3" type="number" id="CreditCard_CardNumber3" readonly required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;" />
<input class="card-box card-box-4" type="number" id="CreditCard_CardNumber4" readonly required step="1" minlength="4" maxlength="4" pattern="[0-9]{4}" value="" placeholder="0000"
onClick="this.setSelectionRange(0, this.value.length)" oninput="this.value=this.value.slice(0,this.maxLength||'');this.value=(this.value < 1) ? ('') : this.value;" />
</div>
Réponse vérifiée a un problème qui met en évidence le champ précédent si la longueur du champ précédent est valide
J'ai modifié la réponse ci-dessus pour corriger la longueur complète de la balise précédente
var container = document.getElementsByClassName("container")[0];
container.onkeyup = function(e) {
var target = e.srcElement || e.target;
var maxLength = parseInt(target.attributes["maxlength"].value, 10);
var myLength = target.value.length;
if (myLength >= maxLength) {
var next = target;
while (next = next.nextElementSibling) {
if (next == null)
break;
if (next.tagName.toLowerCase() === "input") {
next.focus();
break;
}
}
}
// Move to previous field if empty (user pressed backspace)
else if (myLength === 0) {
var previous = target;
// Move to previous field if backspace is pressed
if (code == 8) {
previous = previous.previousElementSibling;
if (previous != null) {
if (previous.tagName.toLowerCase() === "input") {
previous.focus();
}
}
} else {
while (previous = previous.previousElementSibling) {
if (previous == null)
break;
if (previous.tagName.toLowerCase() === "input") {
var mLength = parseInt(previous.attributes["maxlength"].value, 10);
var pMyLength = previous.value.length;
// Move to previous field if it does not have required length
if (mLength == pMyLength) {
break;
} else {
previous.focus();
break;
}
}
}
}
}
}
Le code btevfik mis à jour, Onkeyup ou onkeydown créera un problème pour la navigation par onglets. Il sera difficile d’éditer ou de modifier le texte dans la zone de saisie car il sera limité à maxlength. Nous pouvons donc utiliser l'événement oninput pour accomplir la tâche.
HTML
<ul>
<li>a: <input type="text" maxlength="5" /></li>
<li>b: <input type="text" maxlength="3" /></li>
<li>c: <input type="text" maxlength="5" /></li>
<li>d: <input type="text" maxlength="3" /></li>
<li>e: <input type="text" maxlength="6" /></li>
<li>f: <input type="text" maxlength="10" /></li>
<li>g: <input type="text" maxlength="7" /></li>
</ul>
Javascript
$(document).ready(function(){
$('input').on("input", function(){
if($(this).val().length==$(this).attr("maxlength")){
$(this).next().focus();
}
});
});
CSS
ul {list-style-type:none;}
li {padding:5px 5px;}
Si vous ajoutez des champs de texte de saisie de manière dynamique, vous pouvez essayer ceci.
Cela réinjectera le script dans le DOM et fonctionnera parfaitement.
$('body').on('keyup', '#num_1',function(){
if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
$('#num_2').focus();
}
})
$('body').on('keyup','#num_2', function(){
if (this.value.length === parseInt(this.attributes["maxlength"].value)) {
$('#num_3').focus();
}
})
<input type="text" class="form-control" name="number" maxlength="3" id="num_1">
<input type="text" class="form-control" name="number" maxlength="3" id="num_2">
<input type="text" class="form-control" name="number" maxlength="4" id="num_3">