Ограничение символов в поле ввода для набора символов

Обновление вопроса:. Как я могу запретить вводить все символы, кроме тех, которые указаны в массиве char, в поле ввода, используя AngularJS (или jQuery)?


Старый вопрос:

У меня есть простое поле <input type="text" /> в моем приложении AngularJS, и я хочу, чтобы пользователь мог вводить только следующие символы в поле:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !\"#$%&'()*+,-./:;<=>[email protected][\\]^_`{|}~

Я знаю, что я могу добавить ng-pattern="allowed" в <input>, а затем установить $scope.allowed в некоторый шаблон регулярного выражения, и это будет означать, что вход недействителен, если введены недопустимые символы, но я также хочу запретить ограниченные символы из вводится в поле AT ALL.

Итак, мой вопрос состоит из двух вопросов:

  • Какой шаблон регулярного выражения я использую, чтобы ограничить набор символов указанным выше?
  • Как предотвратить ввод запрещенных символов в поле? (например, если вы вводите строчную букву, то она не появится в поле для начала, аналогично, если вы попытаетесь вставить текст, содержащий любые незаконные символы, они будут немедленно удалены)

Ответ 1

Чтобы "ограничить некоторые символы от ввода", что приходит мне в голову, это присоединить обработчики событий для "keyup", "change", "paste" событий на входах и когда они запускаются, чтобы "очистить" их значения от ваш шаблон. Я реализовал логику как плагин jQuery, но вы можете приспособить его к angular, используйте лучшее имя или что хотите.

Плагин:

$.fn.restrictInputs = function(restrictPattern){
    var targets = $(this);

    // The characters inside this pattern are accepted
    // and everything else will be 'cleaned'
    // For example 'ABCdEfGhI5' become 'ABCEGI5'
    var pattern = restrictPattern || 
        /[^0-9A-Z !\\"#$%&'()*+,\-.\/:;<=>[email protected]\[\]^_`{|}~]*/g; // default pattern

    var restrictHandler = function(){
        var val = $(this).val();
        var newVal = val.replace(pattern, '');

        // This condition is to prevent selection and keyboard navigation issues
        if (val !== newVal) {
            $(this).val(newVal);
        }
    };

    targets.on('keyup', restrictHandler);
    targets.on('paste', restrictHandler);
    targets.on('change', restrictHandler);
};

Использование:

$('input').restrictInputs();

// Or ...

$('.my-special-inputs-decorated-with-this-class').restrictInputs();

Вот JsFiddle Demo

Примечание. Вы можете попытаться изменить реализацию, чтобы принять строку с запрещенными символами вместо регулярного выражения и динамически создать реджикс. Также вы можете найти другие события, которые подходят для запуска "очистки".

Ответ 2

Angular способ сделать это - использовать Angular ngModelController. $parsers См. документацию :

$parsers

Массив функций для выполнения, как конвейер, всякий раз, когда управление считывает значение из DOM. Каждая функция называется, в свою очередь, передавая значение до следующего. Используется последнее возвращаемое значение для заполнения модели. Используется для дезинфекции/преобразования значения, а также Проверка. Для проверки синтаксические анализаторы должны обновить срок действия с использованием $setValidity() и return undefined для недопустимых значений.

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

app.directive('inputRestrictor', [
  function() {
    return {
      restrict: 'A',
      require: 'ngModel',
      link: function(scope, element, attr, ngModelCtrl) {
        var pattern = /[^0-9A-Z !\\"#$%&'()*+,\-.\/:;<=>[email protected]\[\]^_`{|}~]*/g;

        function fromUser(text) {
          if (!text)
            return text;

          var transformedInput = text.replace(pattern, '');
          if (transformedInput !== text) {
            ngModelCtrl.$setViewValue(transformedInput);
            ngModelCtrl.$render();
          }
          return transformedInput;
        }
        ngModelCtrl.$parsers.push(fromUser);
      }
    };
  }
]);

Вот демон plnkr.

* Шаблон регулярного выражения для указанной выше директивы, взятой из ответа Виктора Бахтева.

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

Ответ 3

Попробуйте использовать regExp для фильтрации ненужных символов на ng-keypress, передав $event.

# Это будет более ясно в plnk!