0

I want to implement custom validation (Required/Pattern/Disable) through directive in Angular 8:

<input type="text"
      custom-data-annotation
      [(ngModel)]="someValue"
      name="userName" />

I have created the following directive:

@Directive({selector: '[custom-data-annotation]'})
export class CustomDataAnnotationDirective implements OnInit  { 

  constructor(public el: ElementRef, private _renderer: Renderer2) {} 

  ngOnInit() {
    this._renderer.setAttribute(this.el.nativeElement, 'required', 'true'); 
  } 
}

When I run the application and inspect element I can see the required attribute on input field, but when I submit my page without putting any value in that field it always returns false for "myForm.form.invalid"

1 Answer 1

1

To build a validator that works in a template-driven form control, putting a required attribute on the form control is not enough, because angular build its validators at compile time. At runtime, to add a validator dynamically, you'll need to tell angular that your directive is a validation one. Additionally, you must check for the control's validity by yourself. You can do these 2 things by implementing the Validator interface and provide it with NG_VALIDATORS token (see the docs):

@Directive({
  selector: '[custom-data-annotation]',
  // You must provide the class with `NG_VALIDATORS` token
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: CustomDataAnnotationDirective,
      multi: true
    }
  ]
})
export class CustomDataAnnotationDirective implements OnInit, Validator {
  constructor(private _el: ElementRef, private _renderer: Renderer2) {}

  ngOnInit() {
    this._renderer.setAttribute(this._el.nativeElement, 'required', 'true');
  }

  // This method is demanded by the the Validator interface
  validate(control: AbstractControl): { [key: string]: any } | null {
    return !control.value ? { required: true } : null;
  }
}

Stackblitz demo

And... if it's up to you to decide it, consider switching to ReactiveFormsModule, as recommended by @angular docs, for complex forms.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.