web-dev-qa-db-fra.com

Déplacer un focus lorsque le champ de texte saisi atteint une longueur maximale

J'ai un formulaire de numéro de carte de crédit. Le numéro est divisé en quatre parties comme sur une vraie carte de crédit.

Je veux ajouter un goût JavaScript au formulaire où lorsqu'un utilisateur tape quatre lettres dans un champ, le focus passe automatiquement à la balise suivante. Mais pas dans la dernière balise. En faisant cela, un utilisateur n'a pas à taper la touche "tab" pour déplacer un focus.

Il est correct d'ajouter une classe, un identifiant ou un nom supplémentaire dans les balises.

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>MoveFocus</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <script type="text/javascript" charset="utf-8">
     $(function() {
     // some code goes here.
    });
    </script>
</head>


<body>
  <form action="post.php" method="post" accept-charset="utf-8">
    <input type="text" value="" id="first" size="4" maxlength="4"/> -
    <input type="text" value="" id="second" size="4" maxlength="4"/> -
    <input type="text" value="" id="third" size="4" maxlength="4"/> -
    <input type="text" value="" id="fourth" size="4" maxlength="4"/>
    <p><input type="submit" value="Send Credit Card"></p>
  </form>
</body>
</html>
24
TK.

Je n'ai jamais utilisé cet outil auparavant, mais il fait ce que vous voulez. Vous pouvez simplement regarder sa source pour obtenir quelques idées:

Ce plugin sur GitHub

Pour votre situation, vous ajouteriez ce code:

<script type="text/javascript" src="jquery.autotab.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $('#first').autotab({ target: '#second', format: 'numeric' });
    $('#second').autotab({ target: '#third', format: 'numeric', previous: '#first' });
    $('#third').autotab({ previous: '#second', format: 'numeric' });
});
</script>
29
Tauren

Comme d’autres l’ont demandé, ne le faites pas. Les utilisateurs ne pourront pas prévoir que vous les tabulerez automatiquement, ce qui les rendra fous. Avez-vous pensé aux utilisateurs qui copient et collent leur carte de crédit? Quel est l'avantage d'utiliser quatre champs de toute façon?

De plus, toutes les cartes de crédit ne divisent pas leur nombre en quatre ensembles de quatre. American Express les divise par exemple en trois groupes de chiffres. L'ajout et la suppression dynamiques de champs de texte posent des problèmes dans ce cas.

Au lieu de cela, utilisez votre Javascript pour insérer automatiquement les espaces à leur place, en faisant avancer le curseur, pas le focus. Le premier chiffre du numéro indique le type de carte de crédit (5 est Mastercard, 4 est Visa, 3 est American Express…), vous pouvez donc le lire pour décider où ajouter les espaces. Frottez les espaces de la chaîne lorsque vous la publiez. Cette approche vous épargnera à vous et à vos utilisateurs beaucoup de douleur.

17
Michael Zuschlag

Comme l'a suggéré @Sander, le moyen le plus simple de créer un onglet automatique est:

jQuery("form input[type=text]").on('input',function () {
    if(jQuery(this).val().length == jQuery(this).attr('maxlength')) {
        jQuery(this).next("input").focus();
    }
});

Mise à jour par @ morespace54

oninput est un événement html5 est pris en charge sur IE9 +, vous pouvez donc utiliser keyup à la place.

10
Ouadie

Je recommande fortement d'utiliser le plugin Masked Input jQuery. http://digitalbush.com/projects/masked-input-plugin/

Votre utilisation ressemblera à ceci:

$('#creditCardNumber').mask("9999-9999-9999-9999");

De cette façon, vous aurez un support copier-coller.

6
Doguhan Uluca

Si vos champs de formulaire sont l'un à côté de l'autre comme dans votre exemple, vous pouvez simplement profiter de nextElementSibling et voilà!

function skipIfMax(element) {
  max = parseInt(element.dataset.max)
  
  
  if (element.value.length >= max && element.nextElementSibling) {
    element.nextElementSibling.focus();  
  }
}
<input type="text" data-max=2 oninput="skipIfMax(this)"/>
<input type="text" data-max=3 oninput="skipIfMax(this)"/>
<input type="text" data-max=4 oninput="skipIfMax(this)"/>
<input type="text" data-max=5 oninput="skipIfMax(this)"/>
5
Marcelo Lazaroni

Une solution très simple pourrait aller comme ceci:

<script type="text/javascript">
    function input_onchange(me){ 
        if (me.value.length != me.maxlength){
            return;
        }
        var i;
        var elements = me.form.elements;
        for (i=0, numElements=elements.length; i<numElements; i++) {
            if (elements[i]==me){
                break;
            }
        }
        elements[i+1].focus();
    }
</script>
<form action="post.php" method="post" accept-charset="utf-8">
    <input type="text" value="" id="first" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <input type="text" value="" id="second" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <input type="text" value="" id="third" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <input type="text" value="" id="fourth" size="4" maxlength="4"
        onchange="input_onchange(this)"
    /> -
    <p><input type="submit" value="Send Credit Card"></p>
</form>
1
Roland Bouman

Je ne l'ai pas testé, mais je pense que cela fonctionnera. Il déplacera probablement le focus sur le bouton lorsque le 4ème champ sera terminé.

$("form input").change(function () {
    var maxLength = $(this).attr('maxlength');

    if($(this).val().length == maxLength) {
        $(this).next().focus();
    }
}
0
Sander Rijken

Celui-ci n'a pas quatre champs, mais il valide les cartes de crédit (contrôle d'intégrité, pas l'algorithme de Luhn!). Je dois vous dire à quel point il est ennuyeux d'utiliser plusieurs champs pour un utilisateur et une tabulation automatique. Je vous recommande de n'utiliser qu'un seul champ.

De site web jquery:

$("#myform").validate({
  rules: {
    field: {
      required: true,
      creditcard: true
    }
  }
});

/

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
                    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
  <script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/lib/jquery.delegate.js"></script>
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/jquery.validate.js"></script>
<script type="text/javascript">
jQuery.validator.setDefaults({
    debug: true,
    success: "valid"
});;
</script>

  <script>
  $(document).ready(function(){
    $("#myform").validate({
  rules: {
    field: {
      required: true,
      creditcard: true
    }
  }
});
  });
  </script>
  <style>#field { margin-left: .5em; float: left; }
    #field, label { float: left; font-family: Arial, Helvetica, sans-serif; font-size: small; }
    br { clear: both; }
    input { border: 1px solid black; margin-bottom: .5em;  }
    input.error { border: 1px solid red; }
    label.error {
        background: url('http://dev.jquery.com/view/trunk/plugins/validate/demo/images/unchecked.gif') no-repeat;
        padding-left: 16px;
        margin-left: .3em;
    }
    label.valid {
        background: url('http://dev.jquery.com/view/trunk/plugins/validate/demo/images/checked.gif') no-repeat;
        display: block;
        width: 16px;
        height: 16px;
    }
</style>
</head>
<body>

<form id="myform">
  <label for="field">Required, creditcard (try 446-667-651): </label>
  <input class="left" id="field" name="field" />
  <br/>
  <input type="submit" value="Validate!" />
</form>

</body>
</html>
0
user195488