Why is Angularjs ng-pattern not working with the following regexp?
Asked Answered
O

3

16

For some reason the initialized value doesn't appear in the field, but the second field without the ng-pattern does work. any ideas?

    angular.module('app', []).controller('MainCtrl', function($scope) {
      $scope.widget = {title: 'abc', title2: 'abc'};
    });

    <div ng-app="app" ng-controller="MainCtrl">
     <input ng-model="widget.title" required ng-pattern="/[a-zA-Z]{4}[0-9]{6,6}[a-zA-Z0-9]{3}/">
     <br /><br />   
     input 1: {{ widget.title }}
     <br /><br />   
     <input ng-model="widget.title2" required>
     <br /><br />   
     input 2: {{ widget.title2 }}
    </div>

Here is the Fiddle http://jsfiddle.net/wkzab/1/

Outlying answered 9/4, 2014 at 3:10 Comment(3)
It seems as though the first input doesn't show up until it matches the regex, for example try: abcZ123456ABC.Hellfire
I'm looking to validate strings in the form of ABCD123456X3ZOutlying
Thanks @Hellfire but do you know why? I mean, what's the logic behind this?Outlying
H
19

UPDATE

I looked into it a bit (never really used Angular), and by using the name attribute on the form and inputs, you can grab an error like shown in my newest JSFiddle. Its in the format: {{formName.inputName.$error}}. This returns an object with parameters that equal a boolean. So {{form.title.$error.pattern}} will be true when there is an error with the regular expression (so you would display the error). I also cleaned (works the same) your regex to: /^[A-Z]{4}\d{6}[A-Z\d]{3}$/i.


OLD

The ng-pattern attribute attempts to match the field based on this regular expression: /[a-zA-Z]{4}[0-9]{6,6}[a-zA-Z0-9]{3}/. This translates to 4 alphabetical characters, 6 digits, and 3 alphanumeric characters. Once you have a matching pattern, it will show up.

You should be able to remove the ng-pattern attribute or change the expression to be less specific. For example, this JSFiddle will accept any value as long as the entire string is alphanumeric. Update the question if you want help with a different pattern.

Hellfire answered 9/4, 2014 at 3:18 Comment(6)
Great answer, the thing is I'm looking to validate that pattern (ABCD123456X3Z) which is the mexican tax id number, and I want to be able to show an error message like: The string ABCDEF that you entered is not valid. Where "ABCDEF" is the user input.Outlying
Thanks for your time and effort @Hellfire your rock! but I'm still unable to access the field's value when it hasn't matched the pattern. Maybe this is the way angular is supposed to work? Should I just accept this? The two weird behaviors are: 1. On page load the first field doesn't contain the initial value that was set on the controller. 2. As soon as I start typing, the "title" attribute in the "widget" object disappears. (I know that it appears again when it matches de pattern)Outlying
Not quite sure if that's an intended Angular behavior, or if there is a way around it. I would assume its intended though. Think if you have a model with a property zip that must match [0-9]{5}, you them use this zip to query a database for restaurants. If the default value (or the value someone inputs) is "abc", should zip equal "abc" or null? I think null so it isn't used elsewhere (i.e. incorrectly querying the DB).Hellfire
I still think this is weird. One should be able to access the value even if it is incorrect so you can tell the user.. "the value" is not a valid value. Anyway I'll mark your answer as correct for pointing all of these things out.Outlying
I agree its a little odd. Even though the documentation doesn't seem to specifically say it works like this or how to work around it, you can see that it is normal behavior if you replace the last name to something too short in their example.Hellfire
You're right, same issue in their example. Thanks a lot @Hellfire !Outlying
Z
49

I too was facing same problem. Found a workaround to do this.

You have to do something like this in your controller.

$scope.myRegex = /[a-zA-Z]{4}[0-9]{6,6}[a-zA-Z0-9]{3}/; (don't put expression in quotes)

Finally

<input ng-model="widget.title" required ng-pattern="myRegex">

It will now be working.

Zara answered 25/8, 2014 at 11:12 Comment(9)
Argh! Just spent like an hour trying to figure out why the pattern wasn't working. I was putting it directly in the attribute pattern then ng-pattern They really need to document that better. Thanks!Orfinger
@ved , what if am getting regular expression as string from there server, i mean , i have $scope.myRegex = "/[a-zA-Z]{4}[0-9]{6,6}[a-zA-Z0-9]{3}/"; any way now?Aniakudo
@Vivek Take a case, if you put regex as string, i mean inside " ", Now how you write a regex that will match a quotes. For detailed information please visit : developer.mozilla.org/en/docs/Web/JavaScript/Guide/….Zara
Just a side note, In my controller I have wrapped the regex in quotes and it still works.Consultative
@Consultative can you create a fiddle of your code. I will show you the difference.Zara
@Zara here is my regex that I am using "[a-zA-Z._^%$#!~@,']+"Consultative
Please post a fiddle, so that I can check how you are using it.Zara
Thanks for mentioning not to put it in quotes - that was my issueCrowned
Just for information, if you are copy-pasting regex in to Intellij IDEA, then you might see that '\' is replaced with double '\\'. Even pattern on HTML looks the same, input does not getting validated! So replace double slashes with single. jsfiddle.net/wkzab/1492Birkenhead
H
19

UPDATE

I looked into it a bit (never really used Angular), and by using the name attribute on the form and inputs, you can grab an error like shown in my newest JSFiddle. Its in the format: {{formName.inputName.$error}}. This returns an object with parameters that equal a boolean. So {{form.title.$error.pattern}} will be true when there is an error with the regular expression (so you would display the error). I also cleaned (works the same) your regex to: /^[A-Z]{4}\d{6}[A-Z\d]{3}$/i.


OLD

The ng-pattern attribute attempts to match the field based on this regular expression: /[a-zA-Z]{4}[0-9]{6,6}[a-zA-Z0-9]{3}/. This translates to 4 alphabetical characters, 6 digits, and 3 alphanumeric characters. Once you have a matching pattern, it will show up.

You should be able to remove the ng-pattern attribute or change the expression to be less specific. For example, this JSFiddle will accept any value as long as the entire string is alphanumeric. Update the question if you want help with a different pattern.

Hellfire answered 9/4, 2014 at 3:18 Comment(6)
Great answer, the thing is I'm looking to validate that pattern (ABCD123456X3Z) which is the mexican tax id number, and I want to be able to show an error message like: The string ABCDEF that you entered is not valid. Where "ABCDEF" is the user input.Outlying
Thanks for your time and effort @Hellfire your rock! but I'm still unable to access the field's value when it hasn't matched the pattern. Maybe this is the way angular is supposed to work? Should I just accept this? The two weird behaviors are: 1. On page load the first field doesn't contain the initial value that was set on the controller. 2. As soon as I start typing, the "title" attribute in the "widget" object disappears. (I know that it appears again when it matches de pattern)Outlying
Not quite sure if that's an intended Angular behavior, or if there is a way around it. I would assume its intended though. Think if you have a model with a property zip that must match [0-9]{5}, you them use this zip to query a database for restaurants. If the default value (or the value someone inputs) is "abc", should zip equal "abc" or null? I think null so it isn't used elsewhere (i.e. incorrectly querying the DB).Hellfire
I still think this is weird. One should be able to access the value even if it is incorrect so you can tell the user.. "the value" is not a valid value. Anyway I'll mark your answer as correct for pointing all of these things out.Outlying
I agree its a little odd. Even though the documentation doesn't seem to specifically say it works like this or how to work around it, you can see that it is normal behavior if you replace the last name to something too short in their example.Hellfire
You're right, same issue in their example. Thanks a lot @Hellfire !Outlying
E
1

Yes indeed! This was causing me an issue to...leaving the quotes out is what fixed it for me.

 $scope.regVal= /([A-Z]{3}\s?(\d{3}|\d{2}|d{1})\s?[A-Z])|([A-Z]\s?(\d{3}|\d{2}|\d{1})\s?[A-Z]{3})|(([A-HK-PRSVWY][A-HJ-PR-Y])\s?([0][2-9]|[1-9][0-9])\s?[A-HJ-PR-Z]{3})/;
Exenterate answered 8/8, 2016 at 22:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.