Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting Characters in Input Field to a Set of Characters

Question Update: How can I prevent all characters except for the ones specified in a char array from being typed into an input field using AngularJS (or jQuery)?


Old Question:

I have a simple <input type="text" /> field in my AngularJS application and I want the user to only be able to enter the following characters into the field:

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

I know that I can add ng-pattern="allowed" to the <input> and then set $scope.allowed to some regex pattern and that will mark the input invalid if any invalid characters are entered, but I also want to prevent restricted characters from being input into the field AT ALL.

So my question is composed of two questions:

  1. What regex pattern do I use to restrict the character set to the one I posted above?
  2. How do I prevent illegal characters from being entered in the field? (e.g. if you type a lowercase letter then it won't appear in the field to begin with, similarly if you try to paste in text containing any illegal characters they will be removed immediately)
like image 241
Kyle V. Avatar asked Aug 20 '14 19:08

Kyle V.


1 Answers

The Angular way to do this is to make use of Angular's ngModelController.$parsers See the documentation:

$parsers

Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. Each function is called, in turn, passing the value through to the next. The last return value is used to populate the model. Used to sanitize / convert the value as well as validation. For validation, the parsers should update the validity state using $setValidity(), and return undefined for invalid values.

Here is an example of a re-usable directive using this approach:

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

Here is a plnkr demo.

*Regex pattern for the above directive taken from Viktor Bahtev answer.

You can obviously extend this directive to take an input parameter as well. I'll leave that for your exersize.

like image 175
Beyers Avatar answered Oct 12 '22 08:10

Beyers