2

I am trying to ensure that the last letter of a field must end with a specific letter in angularjs text field. I have created a function that handles the pattern validation as shown

$scope.validatePattern = function () {
    var typeSelected = $scope.sports_type;
    if (typeSelected == 'Sports') { //the user selected sports from the above model
        $scope.pointPattern = "^[\s\w]+[^(ess|essence)]$";
    }
}

I am using the pattern in below fields.

<label>Sports Option</label>
<input ng-model="option" ng-minlength="3" formcontrol name="option" type="text" ng-pattern="{{pointPattern}}" required>
<p ng-show="frmValidation.option.$invalid" class="input-error-message">Option is required</p>
<p ng-show="frmValidation.option.$error.pattern">Not valid! Must end with ess or essence</p>

why is the ng-pattern not validating that the letter must end with ess or essence

Nitsan Baleli
  • 5,393
  • 3
  • 30
  • 52
user10445503
  • 165
  • 1
  • 12

2 Answers2

1

To match strings ending with ess, essence or sports you may use

$scope.pointPattern = /(?:ess(?:ence)?|sports)$/;

Note that you must use a RegExp variable type. It is equal to $scope.pointPattern = new RegExp("(?:ess(?:ence)?|sports)$"); and it is required if you plan to match a substring in your input string.

If you plan to use a string pattern, you will need to make sure it matches the whole input string:

$scope.pointPattern = "^.*(?:ess(?:ence)?|sports)$";

Pattern details

  • ^ - start of string
  • .* - any 0+ chars other than line break chars
  • (?:ess(?:ence)?|sports) - a non-capturing group matching
    • ess(?:ence)? - ess followed with an optional ence substring
    • | - or
    • sports - a sports substring
  • $ - end of string.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • when I end with ence, its not validating here is it >>> $scope.pointPattern = /(?:ess(?:ence)?|sports)$/; – user10445503 Oct 02 '18 at 12:46
  • If you want to fail the strings ending with `ence` you need `$scope.pointPattern = /(?:ess|ence|sports)$/;` - simple. You may actually tweak the pattern further based on my pattern explanation. E.g. `?` makes a pattern optional, `(?:...)?` makes a sequence optional. `sports?` will match `sport` and `sports`. – Wiktor Stribiżew Oct 02 '18 at 12:48
  • I have a quick observation do not know if you close by – user10445503 Oct 02 '18 at 16:56
  • if I do this goess. It will get validated but it is not supposed to be valid either. It should only be valid when it ends with ess separated by a space – user10445503 Oct 02 '18 at 16:59
  • Do you mean it should be matched as a whole word? `/\b(?:ess|ence|sports)$/`? If you really mean a whitespace: `/(?:^|\s)(?:ess|ence|sports)$/`. – Wiktor Stribiżew Oct 02 '18 at 17:01
0

Your problem is that [^(ess|essence)] is a negated character class that will match one character that is not one of (,e,s,|,n,c or ), also you are looking at the end of the string so you can drop the ^[\s\w]+ part.

I'm assuming that the regex matches valid input so you need to rewrite it as

$scope.pointPattern = "ess(?:ence)?$";

This matches ess possibly followed by ence followed by the end of the string.

JGNI
  • 3,933
  • 11
  • 21