Alexey Sh.
Alexey Sh.

Reputation: 1937

angular ng-pattern strange behaviour

example http://plnkr.co/edit/9o9m3VrtaTAxazDhJNqz?p=preview

I want to use pattern in controller for validation in template

angular.module('app', []).controller('ctrl', function ($scope) {
  $scope.pat = /(\(|\)|\+|\d)+/g;
})

But ng-pattern validate field when input value is 123--

<input type="text" ng-pattern="pat" name='asd' ng-model='asd'>

But inline pattern attribute work fine and notice that 123-- is invalid

<input type="text" pattern="(\(|\)|\+|\d)+" name='asd' ng-model='asd2'>

What I'm doing wrong?

Upvotes: 1

Views: 795

Answers (1)

Daniel Gimenez
Daniel Gimenez

Reputation: 20599

Change your controller to make pat a literal string and not a regex and the behavior will be the same as if you put the pattern directly in the ng-pattern attribute

angular.module('app', []).controller('ctrl', function ($scope) {
  $scope.pat = '(\\(|\\)|\\+|\\d)+';
});

Change the html to use pat the expression.

<input type="text" ng-pattern="{{pat}}" name='asd' ng-model='asd'>

Plunker #1

Apparently ng-pattern when the value is passed as a string makes it so that the entire string is matched from start to end. So it works as though the regex was wrapped with the ^$anchors.

Here is the source from angular.js/validators.js. It shows the regex being converted to a a Regexp if it is a string.

if (isString(regex) && regex.length > 0) {
   regex = new RegExp('^' + regex + '$');
}

So an alternative solution would be to keep your html markup the same and change your controller so that the regular expression matches the entire string by using anchors. If you put the global flag in the expression, then you get some wonky behavior.

angular.module('app', []).controller('ctrl', function ($scope) {
  $scope.pat = /^(\(|\)|\+|\d)+$/;
});

Plunker #2

Upvotes: 1

Related Questions