web-dev-qa-db-fra.com

Comment partitionner le champ de saisie pour apparaître en tant que champs de saisie séparés à l'écran?

Regardez l'image:

 enter image description here

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é?

13
Karan Desai

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 ...

17
Ufuk Onder

Je voudrais juste garder cette approche de 4 champs séparés, et ajouter le même gestionnaire d'événements à tous, ce qui:

  1. Vérifiez si l'entrée est valide (dans la classe de caractères, vous êtes prêt à accepter)
  2. Vérifiez dans quel champ vous vous trouvez, puis déplacez le focus sur le prochain champ ou sur le bouton ok.

Vous pouvez même écrire un petit JS séparé pour cela et le réutiliser.

3
Dan

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>

1
Jagraj Singh

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);
        }
    };

Lien Plunker

Aspect des composants de l'interface utilisateur

https://github.com/amstel91/otp-input-directive

0
Amstel D'Almeida

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?

0
Teshtek