0

I have a reactive form for which the from controls has an array and loop the array to produce a reactive form - my problem is that I want to add a directive for controls that accept only numbers - if I add it in the loop like below it adds the directive in all my input types.

<ng-container *ngFor="let formInput of emergencyContactForm">
        <ng-container [ngSwitch]="formInput.controlType">
             <div *ngSwitchCase="'input'" class="col-4 mb-3" [formGroup]="emergencyContactDetails">
                <label [attr.for]="formInput.key">{{formInput.label}}</label>
                <input [formControlName]="formInput.key" [type]="formInput.type" appNumbericInput />
                <span [appDynamicFormsValidationMessages]="emergencyContactDetails.controls[formInput.key]" [formInputInstance]="formInput"></span>
             </div>
        </ng-container>
 </ng-container>

appNumbericInput is the directive used to restrict the user to enter only numbers in the input type text - But I don't want this directive to be added in all my input fields - My question is that Is there a way to bind the directives to the form control like adding validation to the form control

NumbericInputDirective.ts

@Directive({
  selector: '[appNumbericInput]',
})
export class NumbericInputDirective {
  constructor() { }
@HostListener("keypress", ['$event']) onkeypress(event) {
    return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57;
}

@HostListener('paste', ['$event'])
paste(event) {

    return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57;
}

@HostListener('keyup', ['$event']) onKeyUp(event) {
    let el = <HTMLSelectElement>event.target;
    if (el.value != "") {
        let charList = el.value.substring(0, el.value.length);
        if (charList[0] === "0") {
            el.value = el.value.substring(1, el.value.length);
        }
    }
}
}
dannybucks
  • 2,217
  • 2
  • 18
  • 24
Rahul
  • 2,040
  • 2
  • 11
  • 29

1 Answers1

0

There is no way to set directives contitionally, adding a conditional attribute does not work as angular doesn't recognize it as Directive anymore.

If you don't want to use *ngIf and put the input twice, one with and once without directive, you can tell the directive if it is active or not:

<input [formControlName]="formInput.key" [type]="formInput.type" [appNumbericInput]="isNumericInput" />

Inside the directive you use a Input() to get value

@Input()
appNumbericInput: boolean;

and then check before you apply the directives logic:

if (this.appNumbericInput) {
// place directive logic here
}

Demo here

dannybucks
  • 2,217
  • 2
  • 18
  • 24
  • No - My type will be always a `text` or a `checkbox` - I'm not using `number` type – Rahul Feb 08 '19 at 07:01
  • Ok, but there must be a condition when a input is numeric and when not. So put that condition in there. e.g. [attr.appNumbericInput]="myCondition() ? number : null". The part before the ? can take anything you can put into a if (), it expects a boolean result, true or false. – dannybucks Feb 08 '19 at 07:16
  • If the condition fails - the directive won't get added - Is that your case ? – Rahul Feb 08 '19 at 07:29
  • Actually yes - i will try and let you know – Rahul Feb 08 '19 at 08:02
  • Yeah it doesn't add the directive on input fields which i specified but the directive is not working – Rahul Feb 08 '19 at 10:09
  • Yes, you are right. You need to put the condition check into the directive. I edited my answer and put a demo. This time my approach works! – dannybucks Feb 08 '19 at 13:33