1
votes

I have a custom structural directive (appValidatorErrorMessage) what I want to use in input field of reactive forms. I need structural directive because I want to create new, sibling DOM elements next to input tag. My plan is to create a directive which:

  • checks validation status
  • if input is invalid it adds new class entries (e.g. is-invalid)
  • and then generates validation message from FormControl.errors using 'invalid-feedback' class of Bootstap.

Here is input element with directive:

<input type="email" class="form-control" id="email" [formControl]="email" *appValidatorErrorMessage>

Here I want to check validation status so I need to access FormControl. I don't want to pass it as input attribute.

In attribute directives I can achieve it by injecting NgControl in constructor. If I do the same with structural directives

export class ValidatorErrorMessageDirective implements OnInit {
  constructor(
    private template: TemplateRef<any>,
    private container: ViewContainerRef,
    private control: NgControl,
  ) { }
  ...

I get this error:

NullInjectorError: No provider for NgControl
1
Why you don't try to create custom Validators and put your message in there, it well be simple than directive you made.Titus Sutio Fanpula

1 Answers

0
votes

BTW I want to provide these code:

<input type="text" class="form-control" [formControl]="name" [ngClass]="{'is-invalid' : name.invalid}">
<div class="invalid-feedback" *ngIf="name.invalid">{{getFormControlErrorMessage(name)}}</div>

in a more compact format using a single directive, like this:

  <input type="text" class="form-control" formControlName="name" *appValidatorErrorMessage>

'appValidatorErrorMessage' directive would do the followings:

  • it would detect validation status from FormControl.invalid and it would add 'is-invalid' class for Bootstrap
  • it would generate additional div for error message where error message generated automatically from a service

It's a mixed directive:

  • on the one hand it's an attribute directive: it changes the behavior of the current element
  • on the other hand it's a structural directive since it changes the DOM layout by adding and DOM elements

I found this article how to create mixed directive but I donno how to inject the current FormControl into this directive.