Ограничить ввод HTML только цифрами, с максимальной длиной 5 (игнорировать другие символы)

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

<div class="input text">
    <input id="zip" name="zip" type="number"  min="0" max="99999" ng-model="formData.zip" placeholder="Type here..." class="input-medium" ng-init="0">

Для этого я все еще могу ввести столько цифр, сколько захочу, поэтому атрибуты min max на самом деле ничего не делают.

2 ответа

Решение

Более агрессивный подход, который использует событие keydown и блокирует все нежелательные входные данные с помощью protectDefault:

Изменить: я также включил версию, которая позволяет копировать / вставлять для сравнения, но в этом случае вам нужно использовать keyup, чтобы позволить вставку произойти до исправления вставленного содержимого.

Для любой другой клавиши или комбинации клавиш, которую вы хотите разрешить, вы можете просто добавить их в первый оператор if в качестве разрешенного ввода.

/////////////////////////////////////////////////////
// Super strict version only allows numbers as input
/////////////////////////////////////////////////////
var input = document.getElementById('num');

input.addEventListener('keydown', function(event) {
  // always allow backspace, delete, left/right arrow keys
  if (event.which == 8 || event.which == 46 || event.which == 37 || event.which == 39) { 
    return;
  }
  // prevent all other input if already at 5 chars or not a number
  else if (input.value.length >= 5 || event.which < 48 || event.which > 57) {
    event.preventDefault();
    return;
  }
});

/////////////////////////////////////////////////////
// Version that allows for copy/pasting
/////////////////////////////////////////////////////
var inputPaste = document.getElementById('paste-num');

inputPaste.addEventListener('keydown', function(event) {
  // always allow backspace, delete, left/right arrow, copy, paste, select all
  if (event.which == 8 || event.which == 46 || event.which == 37 || event.which == 39 || (event.ctrlKey && event.which == 67) || (event.ctrlKey && event.which == 86) || (event.ctrlKey && event.which == 65)) { 
    return;
  }
  // prevent all other input if already at 5 chars or not a number
  else if (inputPaste.value.length >= 5 || event.which < 48 || event.which > 57) {
    event.preventDefault();
    return;
  }
});

// clean anything that gets pasted in
inputPaste.addEventListener('keyup', function(event) {
  if (event.ctrlKey && event.which == 86) {
    // remove non numbers
    inputPaste.value = inputPaste.value.replace(/[^0-9]/g, "");
    // trim to first 5 digits
    inputPaste.value = inputPaste.value.substr(0, 5);
  }
});
Numbers Only: <input id="num" name="num" placeholder="#####"> <br>
Numbers Only(can copy/paste):<input id="paste-num" name="paste-num" placeholder="#####">

Вот способ сделать это. На keyup обработчик проверяет входное значение; если в нем более пяти символов, пользователь не сможет добавить его. Если введен нечисловой символ, функция удаляет его.

ОБНОВЛЕНИЕ: Этот код теперь может обрабатывать вставку чисел в начале или в середине пакета, а также, когда пять символов уже присутствуют.

var inputEl = document.getElementById('zip');
var prev = "";

inputEl.addEventListener('keyup', function(e) {
  if (e.which == 8) { // if backspace
    prev = inputEl.value;
    return;
  }
  // check for >5 characters
  if (inputEl.value.length > 5) {
    if (e.which < 48 || e.which > 57) { // if new char is a number
      inputEl.value = prev;
    } else {
      inputEl.value = inputEl.value.slice(0, inputEl.value.length - 1);
    }
    if (inputEl.value.length > 5) { // if still >5 after parsing
      inputEl.value = inputEl.value.slice(0, 5);
    }
  }
  // check for a digit (code 48 to 57)
  else if (e.which < 48 || e.which > 57) {
    (inputEl.value.length > 1) ? inputEl.value = prev: inputEl.value = "";
  }
  prev = inputEl.value;
});

inputEl.focus();
<div class="input text">
  <input id="zip" name="zip" placeholder="Type here...">
</div>

(Фокус был добавлен в поле ввода для удобства тестирования.)

Другие вопросы по тегам