I'm trying to set a regex pattern with a custom Angular directive:
import { Directive, ElementRef } from '@angular/core';
@Directive({
selector: '[appPasswordRegex]',
})
export class PasswordRegexDirective {
constructor(private el: ElementRef) {
this.el.nativeElement.pattern = '^(?=.*?[a-zA-Z])(?=.*?[0-9]).*$';
}
}
HTML:
<input
appPasswordRegex
type="password"
ngModel
name="password"
required
minlength="7"
/>
I also check this.el
in console and pattern property is changed successfully, but it isn't applied in action. Contrary to this, if I just write the pattern inside an input like this below, it works perfectly, even though pattern property is being changed in both cases:
<input
type="password"
ngModel
name="password"
required
pattern="^(?=.*?[a-zA-Z])(?=.*?[0-9]).*$"
minlength="7"
/>
what could be the issue?
CodePudding user response:
When you add a pattern
directly to an input that has ngModel
, you're not just setting the attribute. In the FormsModule
there's a PatternValidator directive that matches that selector and adds the validation around the pattern supplied to the ngModel's FormControl.
To achieve a similar behavior with your directive, you must create a custom validator directive. Here you can find the official documentation on how to create them.
As an example you could do something like this:
@Directive({
selector: '[appPasswordRegex]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: PasswordRegexDirective,
multi: true,
},
],
})
export class PasswordRegexDirective implements Validator {
validate(control: AbstractControl): ValidationErrors {
return /^(?=.*?[a-zA-Z])(?=.*?[0-9]).*$/.test(control.value)
? null
: { invalidPassword: true };
}
}
cheers