Directive to restrict regular expression typing in Angularjs

Asked

Viewed 633 times

1

I wrote a directive to inhibit typing from specifying a regex. However there are two bugs in this solution:

  1. In the first example the input must allow only numbers or point-followed numbers [.], or followed by dot numbers followed by numbers with no more than 4 digits.
    • If I type '1.1111' and go to the beginning of the field and type another digit (in order to have the value '11.1111') , nothing happens. This bug occurs due to the fact that I use the expression elem.val() + event.key in my validator (I used because I do not know how to recover the current value of the input);
  2. The second is the fact that some characters (crase, acute, til, circumflex) are being allowed (press any of them more than once in the field), although the regex does not allow them.

What changes do I have to make to my code to have an effective restriction from regex?

  <html ng-app="app">    
  <head>
    <script data-require="[email protected]" data-semver="1.6.4" src="https://code.angularjs.org/1.6.4/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body>
    <h1>Restrict typing by RegExp</h1>
    PATTERN 1 (^\d+$|^\d+[.]$|^\d+[.]\d{1,4}$) <input type="text" allow-typing="^\d+$|^\d+[.]$|^\d+[.]\d{1,4}$"/><br>
    ONLY NUMBERS <input type="text" allow-typing="^[0-9]+$"/><br>
    ONLY STRINGS <input type="text" allow-typing="^[a-zA-Z]+$"/>
  </body>

</html>

Directive

angular.module('app', []).directive('allowTyping', function() {
  return {
    restrict: 'A',
    link: function(scope, elem, attrs, ctrl) {
      var regex = attrs.allowTyping;
      elem.bind('keypress', function(event) {
        var input = elem.val() + event.key;
        var validator = new RegExp(regex);
        if(!validator.test(input)) {
          event.preventDefault();
          return false;
        }
      });
    }
  };
});
  • I tested your example in Plunker and could not insert special characters (crase, treble, til, circumflex).

  • Strange that I can, both in Firefox and Chrome.

  • I couldn’t get it directly on the keyboard, but I got it from Ctrl+C and Ctrl+V. After inserting these characters with copy and paste, the input box hangs and it is not possible to insert more characters.

  • Um... well remembered. I have to settle this too.

1 answer

3

To solve the problem (2) of diacritics:

<input type="text" allow-typing="^[A-zÀ-ÿ]+$"/>

To solve the problem (1) use timeout and compare the pre and post keydown value. But it still allows you to paste wrong values, use onfocus/onclick + onchange for comparison.

var regex = attrs.allowTyping;
var prevValue = elem.val();

elem.bind('keydown', function(event) {
  var validator = new RegExp(regex);
  var prevValue = this.value;

  setTimeout(function () {
    if (!validator.test(elem.val()))
      elem.val(prevValue);
  }, 1)
});

elem.bind('focus click', function(event) {
  var prevValue = this.value;
});

elem.bind('change', function(event) {
  var validator = new RegExp(regex);

  setTimeout(function () {
    console.log(prevValue, elem.val())
    if (!validator.test(elem.val()))
      elem.val(prevValue);
  }, 1)
});
  • no change why not replace the unauthorized characters by replacing them with ""?

  • More for security even eliminated all invalid entry, because his Regexp has start and end limits. In case only numbers or letters need only delete ^ and $, but more complex expressions can lead to bug generation in thoughtless cases.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.