it-roy-ru.com

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

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

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

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

13
Karan Desai

Вам не нужно хранить 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>

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

17
Ufuk Onder

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

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

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

3
Dan

Надеюсь, что это решение поможет вам. Вы можете удалить onfocus event из input elements, если хотите.

<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

Вы можете использовать следующую директиву, если используете 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

Внешний вид компонента пользовательского интерфейса

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

0
Amstel D'Almeida

Я не знаю, как разделить ввод в 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, если вам нужно это проверить. Помогает это?

0
Teshtek