2
votes

I'm asking here as I suspect there is something with Angular 2 validation patterns that might be different than validation patterns in other languages.

I have a date pattern I used for my asp.net validation to get mm/dd/yyyy, that takes into account leap years etc, and also accepts m/d/yyyy. It is being used as follows.

dateSubmitted: [null, [Validators.required, Validators.pattern('((^(10|12|0?[13578])([/])(3[01]|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(11|0?[469])([/])(30|[12][0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(2[0-8]|1[0-9]|0?[1-9])([/])((1[8-9]\d{2})|([2-9]\d{3}))$)|(^(0?2)([/])(29)([/])([2468][048]00)$)|(^(0?2)([/])(29)([/])([3579][26]00)$)|(^(0?2)([/])(29)([/])([1][89][0][48])$)|(^(0?2)([/])(29)([/])([2-9][0-9][0][48])$)|(^(0?2)([/])(29)([/])([1][89][2468][048])$)|(^(0?2)([/])(29)([/])([2-9][0-9][2468][048])$)|(^(0?2)([/])(29)([/])([1][89][13579][26])$)|(^(0?2)([/])(29)([/])([2-9][0-9][13579][26])$))')]],

This pattern worked perfectly in my asp.net app but it is not in Angular2, it fails whether I try and type the correct date format into the input box or use the material date picker to enter it. I haven't been able to find anything regarding this. I have been successful applying other patterns in Angular2, like email.

My angular versions in my package.json are as follows, if this info is needed:

"@angular/animations": "^4.3.6",
    "@angular/cdk": "^2.0.0-beta.10",
    "@angular/common": "^4.1.0",
    "@angular/compiler": "^4.1.0",
    "@angular/core": "^4.1.0",
    "@angular/forms": "^4.1.0",
    "@angular/http": "^4.1.0",
    "@angular/material": "^2.0.0-beta.10",
    "@angular/platform-browser": "^4.1.0",
    "@angular/platform-browser-dynamic": "^4.1.0",
    "@angular/router": "^4.1.0",
    "@ngrx/core": "^1.2.0",

Edit: added plunker: https://plnkr.co/edit/qHPZceVTpS4x1AEqZfjA

1
Double all \ in the pattern.Wiktor Stribiżew
That didn't quite work, are there other characters I have to escape as well?David
Try copy/pasting the one from here (I double escaped \d there, the fiddle is not working).Wiktor Stribiżew
I tested 9/21/2017 and 09/21/2017, both at that site and on my app, neither worked.David
I'll have to check and see what else might be happening, it works in asp.netDavid

1 Answers

1
votes

The pattern you have been using is not compiled correctly due to \d being treated as a string escape sequence rather than a regex escape sequence. To achieve that, you need to double the backslashes.

Besides, your alternatives are all enclosed with ^ and $ anchors. While it is correct, it does not look quite efficient: it makes sense to put one ^ at the beginning, and one $ at the end of the pattern, while wrapping the alternatives within a non-capturing group.

Also, you may convert all your capturing groups to non-capturing ones (i.e. (...) to (?:...)) to gain some more performance, and replace [/] with a mere / since the / symbol does not need escaping inside RegExp constructor.

So, you may use

dateSubmitted: [null, [Validators.required, Validators.pattern('^(?:(?:10|12|0?[13578])/(?:3[01]|[12][0-9]|0?[1-9])/(?:1[8-9]\\d{2}|[2-9]\\d{3})|(?:11|0?[469])/(?:30|[12][0-9]|0?[1-9])/(?:1[8-9]\\d{2}|[2-9]\\d{3})|0?2/(?:2[0-8]|1[0-9]|0?[1-9])/(?:1[8-9]\\d{2}|[2-9]\\d{3})|0?2/29/[2468][048]00|0?2/29/[3579][26]00|0?2/29/[1][89][0][48]|0?2/29/[2-9][0-9][0][48]|0?2/29/1[89][2468][048]|0?2/29/[2-9][0-9][2468][048]|0?2/29/1[89][13579][26]|0?2/29/[2-9][0-9][13579][26])$')]],

See the updated Plunkr.