Home > Enterprise >  Angular custom directive not working on input pattern
Angular custom directive not working on input pattern

Time:02-17

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

  • Related