Regardez l'image:
Je veux concevoir quelque chose comme dans l'image, où un mot de passe à usage unique (OTP) à 4 chiffres doit être entré par l'utilisateur. Pour le moment, j’ai atteint cet objectif avec 4 entrées distinctes, puis en combinant des valeurs en javascript:
<input type="text" class="form-control" placeholder="0" maxlength="1" />
<input type="text" class="form-control" placeholder="0" maxlength="1" />
<input type="text" class="form-control" placeholder="0" maxlength="1" />
<input type="text" class="form-control" placeholder="0" maxlength="1" />
Je ne suis pas sûr si cette approche est correcte. Je pense qu'il doit y avoir des options de style par lesquelles une zone de texte d'entrée apparaîtra comme une partitionnée, comme dans l'image. Est-il possible d'utiliser bootstrap? Comment styliser un contrôle d’entrée pour qu’il apparaisse comme un champ d’entrées partitionné?
Vous ne devez pas garder 4 champs distincts;
Commencez par ajuster l'espacement des caractères, puis ajustez le style de la bordure du bas ...
#partitioned {
padding-left: 15px;
letter-spacing: 42px;
border: 0;
background-image: linear-gradient(to left, black 70%, rgba(255, 255, 255, 0) 0%);
background-position: bottom;
background-size: 50px 1px;
background-repeat: repeat-x;
background-position-x: 35px;
width: 220px;
}
<input id="partitioned" type="text" maxlength="4" />
- EDIT pour fixer 5 soulignements pour 4 caractère laid--
var obj = document.getElementById('partitioned');
obj.addEventListener("keydown", stopCarret);
obj.addEventListener("keyup", stopCarret);
function stopCarret() {
if (obj.value.length > 3){
setCaretPosition(obj, 3);
}
}
function setCaretPosition(elem, caretPos) {
if(elem != null) {
if(elem.createTextRange) {
var range = elem.createTextRange();
range.move('character', caretPos);
range.select();
}
else {
if(elem.selectionStart) {
elem.focus();
elem.setSelectionRange(caretPos, caretPos);
}
else
elem.focus();
}
}
}
#partitioned {
padding-left: 15px;
letter-spacing: 42px;
border: 0;
background-image: linear-gradient(to left, black 70%, rgba(255, 255, 255, 0) 0%);
background-position: bottom;
background-size: 50px 1px;
background-repeat: repeat-x;
background-position-x: 35px;
width: 220px;
min-width:220px;
}
#divInner{
left: 0;
position: sticky;
}
#divOuter{
width:190px;
overflow:hidden
}
<div id="divOuter">
<div id="divInner">
<input id="partitioned" type="text" maxlength="4" />
</div>
<div>
Je pense que cela peut être un point de départ ... espérons que cela vous aidera ...
Je voudrais juste garder cette approche de 4 champs séparés, et ajouter le même gestionnaire d'événements à tous, ce qui:
Vous pouvez même écrire un petit JS séparé pour cela et le réutiliser.
J'espère que cette solution vous aidera. Vous pouvez supprimer onfocus event de input elements si vous le souhaitez.
<body>
<head>
<style>
input[type=number] {
height: 45px;
width: 45px;
font-size: 25px;
text-align: center;
border: 1px solid #000000;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
</style>
<script>
function getCodeBoxElement(index) {
return document.getElementById('codeBox' + index);
}
function onKeyUpEvent(index, event) {
const eventCode = event.which || event.keyCode;
if (getCodeBoxElement(index).value.length === 1) {
if (index !== 4) {
getCodeBoxElement(index+ 1).focus();
} else {
getCodeBoxElement(index).blur();
// Submit code
console.log('submit code ');
}
}
if (eventCode === 8 && index !== 1) {
getCodeBoxElement(index - 1).focus();
}
}
function onFocusEvent(index) {
for (item = 1; item < index; item++) {
const currentElement = getCodeBoxElement(item);
if (!currentElement.value) {
currentElement.focus();
break;
}
}
}
</script>
</head>
<body>
<form>
<input id="codeBox1" type="number" maxlength="1" onkeyup="onKeyUpEvent(1, event)" onfocus="onFocusEvent(1)"/>
<input id="codeBox2" type="number" maxlength="1" onkeyup="onKeyUpEvent(2, event)" onfocus="onFocusEvent(2)"/>
<input id="codeBox3" type="number" maxlength="1" onkeyup="onKeyUpEvent(3, event)" onfocus="onFocusEvent(3)"/>
<input id="codeBox4" type="number" maxlength="1" onkeyup="onKeyUpEvent(4, event)" onfocus="onFocusEvent(4)"/>
</form>
</body>
</body>
Vous pouvez utiliser la directive ci-dessous si vous utilisez AngularJS
Dans votre HTML ajouter
<div otp-input-directive options="otpInput"></div>
Dans votre contrôleur, ajoutez
$scope.otpInput={
size:6,
type:"text",
onDone: function(value){
console.log(value);
},
onChange: function(value){
console.log(value);
}
};
Je ne sais pas comment scinder une entrée en html5. Peut-être qu'en css, vous pouvez utiliser la même classe pour contrôler votre entrée et vous pouvez utiliser une entrée de style, quelque chose comme:
div{
text-align:center;
background:#eee;
}
input{
border: 0;
outline: 0;
background: transparent;
border-bottom: 2px solid black;
width: 100px;
text-align:center;
padding : 5px;
margin-left:10px;
}
button{
margin-top:20px !important;
margin: 0 auto;
color: white;
border-radius: 4px;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
}
<div>
<input class="form-control" placeholder="0" maxlength="1" />
<input class="form-control" placeholder="0" maxlength="1" />
<input class="form-control" placeholder="0" maxlength="1" />
<input class="form-control" placeholder="0" maxlength="1" />
<br><button type="button" onclick="myFunction()">Submit</button>
<p id="optRes"></p>
</div>
Définissez myFunction () et vous pouvez obtenir votre tableau par classe: contrôle de forme, conversion en chaîne puis en int si vous devez le vérifier. Cela aide?