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>
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:
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>
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.
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.
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.
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)"/>
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>
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();
}
}
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.
$("#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>