Ввод HTML, который принимает только числа и символ +

Я пытаюсь создать пользовательский ввод текста для телефонных номеров, который принимает только числа и символ плюса (+); все остальные символы должны быть отброшены и не показаны в поле.

Я пытаюсь сделать это с помощью обработчика событий (onkeydown/onkeypress) и отбрасывания входов, соответствующих другим клавишам. Однако я не могу понять, как это сделать. Вот подходы, которые я пробовал и не работаю:

  • Используя событие onkeypress и посмотрите на event.key, чтобы выяснить, какой ключ был нажат: не работает в Chrome (см. http://caniuse.com/keyboardevent-key). Есть ли способ обхода браузера?

  • Использование события onkeycode и просмотр event.keyCode: не работает, когда нам нужно нажимать несколько клавиш для печати символа (например, для раскладки клавиатуры на английском языке требуется нажать Shift и = дать +). Кроме того, он позволяет отображать символы, такие как! @# $% & *(), поскольку они появляются при нажатии Shift и числа. (Это подход, используемый в JavaScript-кодовом коде, разрешает только число и плюс символ, но мне это не очень помогает;))

  • Используя атрибут HTML-шаблона:, на самом деле это не мешает людям писать то, что им нравится.

Спасибо!

Ответ 1

Существует другое решение, вы можете использовать Array.prototype.filter() для удаления плохих символов и Array.prototype.join(), чтобы воссоздать строку перед ее вставкой во вход.

Вы можете использовать oninput событие. Он выполняет JavaScript, когда пользователь пишет что-то в поле <input>.


См. пример ниже

var inputEl = document.getElementById('tel');
var goodKey = '0123456789+ ';

var checkInputTel = function(e) {
  var key = (typeof e.which == "number") ? e.which : e.keyCode;
  var start = this.selectionStart,
    end = this.selectionEnd;

  var filtered = this.value.split('').filter(filterInput);
  this.value = filtered.join("");

  /* Prevents moving the pointer for a bad character */
  var move = (filterInput(String.fromCharCode(key)) || (key == 0 || key == 8)) ? 0 : 1;
  this.setSelectionRange(start - move, end - move);
}

var filterInput = function(val) {
  return (goodKey.indexOf(val) > -1);
}

inputEl.addEventListener('input', checkInputTel);
<input type='tel' id='tel' />

Ответ 3

Firtly, всегда старайтесь выполнять проверку на стороне сервера, это означает "помочь" пользователю, а не проверять данные (вы всегда можете открыть консоль и изменить значение входного значения, как вы хотите)

Теперь метод, который я использовал бы:

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

// Test regex
var phoneRegExp = new RegExp(/^(?=.*[0-9])[+0-9]+$/);

$('#tel').change(function() {
    var val = $(this).val();
    if ( !phoneRegExp.test( val ) ) {
        // Replace anything that isn't a number or a plus sign
        $(this).val( val.replace(/([^+0-9]+)/gi, '') );
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="tel" id="tel">

Ответ 4

использовать ввод

type = "tel" или "phone"

Показывает номерную строку по умолчанию на мобильных телефонах.

Надеюсь, это поможет:)

Ответ 5

Этот надежный общий подход вдохновлен ответом @R3tep. Он позволяет определять шаблоны регулярных выражений с помощью атрибута data-filter, аналогичного атрибуту :

// Apply filter to all inputs with data-filter:
let inputs = document.querySelectorAll('input[data-filter]');

for (let input of inputs) {
  let state = {
    value: input.value,
    start: input.selectionStart,
    end: input.selectionEnd,
    pattern: RegExp('^' + input.dataset.filter + '$')
  };
  
  input.addEventListener('input', event => {
    if (state.pattern.test(input.value)) {
      state.value = input.value;
    } else {
      input.value = state.value;
      input.setSelectionRange(state.start, state.end);
    }
  });

  input.addEventListener('keydown', event => {
    state.start = input.selectionStart;
    state.end = input.selectionEnd;
  });
}
<input type='tel' data-filter='[0-9|+]*' placeholder='123+456'>
<input type='tel' data-filter='(\+|(\+[1-9])?[0-9]*)' placeholder='+10123'>
<input type='text' data-filter='([A-Z]?|[A-Z][a-z]*)' placeholder='Abcdefg'>
<input type='text' data-filter='([A-Z]{0,3}|[A-Z]{3}[0-9]*)' placeholder='ABC123'>

Ответ 6

Используя комбинацию прослушивателя событий keyup, некоторых методов сравнения RegEx/String и промежуточной переменной, я смог придумать следующее:

var ele = document.getElementById('phone');
var curr = "";
var regexPatt = /^(0|[1-9][0-9]*)$/;
ele.addEventListener('keyup',function(e){
  var code = e.keyCode || e.which;
  if(this.value.match(regexPatt) || this.value.indexOf('+') > -1 || code == 8){
    curr = this.value;
    this.value = curr;
  } else {
    this.value = curr;
  }
});

Взгляните на скрипку: https://jsfiddle.net/Lg31pomp/2/

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

Ответ 7

Ваш вход должен выглядеть примерно так:

<input type="text" onkeypress='return isNumberKey(event);'>

и это script:

function isNumberKey(evt) {
    var charCode = (evt.which) ? evt.which : event.keyCode;
    console.log(charCode);
    if (charCode != 43 &&  charCode > 31
        && (charCode < 48 || charCode > 57))
        return false;

    return true;
}

Это одно из многих возможных решений.