Как разбить поле ввода на отдельные поля ввода на экране?

смотреть на изображение:

enter image description here

Я хочу создать что-то вроде изображения, где 4-значный одноразовый пароль (OTP) должен быть введен пользователем. Прямо сейчас я достиг этого с помощью 4 отдельных входов, а затем объединения значений в 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" />

Я не уверен, что это правильный подход. Я думаю, что должны быть некоторые параметры стиля, с помощью которых одно входное текстовое поле будет отображаться как секционированное, как на изображении. Это возможно используя bootstrap? Как стиль входного контроля должны появиться в виде отдельных местах входов?

5 ответов


вы не должны держать 4 отдельных полей;

сначала вы должны настроить интервал символов, а затем настроить стиль границы дна...

#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, чтобы исправить 5 подчеркиваний для 4 символов уродства--

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>

Я думаю, что это может стать отправной точкой... надеюсь, это поможет...


Я бы просто сохранил этот подход к 4 отдельным полям и добавил один и тот же обработчик событий ко всем из них, который будет:

  1. проверьте правильность ввода (в классе символов вы готовы принять)
  2. проверьте, в каком поле вы находитесь, а затем переместите фокус на следующее поле или кнопку ok.

вы даже можете написать небольшой отдельный JS для этого, и повторно использовать его.


Я не знаю, как разделить вход в html5, возможно, в css вы можете использовать тот же класс для управления своим входом, и вы можете ввести стиль, что-то вроде :

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>    

определите myFunction (), и вы можете получить свой массив своим классом : form-control, преобразовать в строку, а затем в int, если вам нужно его проверить . Помогает ?


вы можете использовать приведенную ниже директиву, если используете AngularJS

в вашем HTML добавить

<div otp-input-directive options="otpInput"></div>

в контроллере добавить

$scope.otpInput={
        size:6,
        type:"text",
        onDone: function(value){
            console.log(value);
        },
        onChange: function(value){
            console.log(value);
        }
    };

Plunker link

UI компонент внешний вид

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


надеюсь, это решение поможет вам. Вы можете удалить onfocus событие вход элементы, если вы хотите.

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