0

I created a custom Angular directive called myRequiredDirective. I want to conditionally apply it to an input control similar to how it can be done with [required]:

<input class="form-control" [required]="false" />

However, when I try to do something similar with my myRequiredDirective, I get an error: Can't bind to 'myRequiredDirective' since it isn't a known property of 'input'.

directive.ts

import { Directive, Input, OnChanges, SimpleChanges } from '@angular/core';
import { Validator, AbstractControl, Validators, NG_VALIDATORS, ValidatorFn } from '@angular/forms';

@Directive({
    selector: '[myRequiredDirective]',
    providers: [{ provide: NG_VALIDATORS, useExisting: MyRequiredDirective, multi: true }]
})

export class MyRequiredDirective implements Validator {

    private valFn = CustomValidator();

    validate(control: AbstractControl): { [key: string]: any } {
        return this.valFn(control);
    }

}

function CustomValidator(): ValidatorFn {

    return (control: AbstractControl): { [key: string]: any } => {
        let isValid = true;

        if (!control.value) {
            isValid = false;
        }

        if (control.value == 0) {
            // Set control invalid if value equals zero. Mainly used for drop downs where the default value is usually 0.
            isValid = false;
        }

        return isValid ? null : { 'required': 'message will come from validators.component.html' };
    };
}

Is there a way I can make my custom directive behave similar to [required]?

Edit #1

I solved the Can't bind to 'myRequiredDirective' since it isn't a known property of 'input'. by doing the following:

export class MyRequiredDirective implements Validator {

    @Input() myRequiredDirective: boolean;
    
    private valFn = CustomValidator(this.myRequiredDirective); // this.myRequiredDirective is undefined

    validate(control: AbstractControl): { [key: string]: any } {
        return this.valFn(control);
    }

}

and in the HTML template:

<input class="form-control" [myRequiredDirective]="false" />

However, this.myRequiredDirective is undefined when I try to pass it into the CustomValidator.

Community
  • 1
  • 1
Ryan Buening
  • 1,559
  • 2
  • 22
  • 60
  • 1
    Does this help? https://stackoverflow.com/questions/40705819/angular2-cant-bind-to-directive-since-it-isnt-a-known-property-of-element – David Feb 05 '18 at 21:11
  • @David thanks, that fixes the `Can't bind to 'myRequiredDirective' since it isn't a known property of 'input'.` error. However, when I try: ``, my directive still runs and sets the input as required. Any ideas? – Ryan Buening Feb 05 '18 at 21:17
  • 1
    You don't seem to be checking for that value you pass to the directive to see if the control is required or not – David Feb 05 '18 at 21:22
  • @David see my Edit #1 in the question above. How do I get the value being passed in from my HTML template? – Ryan Buening Feb 06 '18 at 14:20

1 Answers1

0

You could do something like this:

<input *ngIf="!condition4directive" class="form-control"/>
<input *ngIf="condition4directive" class="form-control" myRequiredDirective/>
mohsenmadi
  • 2,277
  • 1
  • 23
  • 34