Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply Angular validation class to non-FormControl parent

I have a reactive form, where each control follows this basic structure:

<div class="form-group">
    <label for="vtype">Vehicle Type</label>
    <input formControlName="vtype" class="form-control" placeholder="Type"/>
</div>

Angular automatically adds validation classes to each FormControl and FormGroup, such as ng-valid, ng-touched, ng-dirty, etc.

For styling purposes, I would also like to apply these same classes to the control's parent div element. For example:

<div class="form-group ng-dirty ng-touched ng-invalid">
    <label for="vtype">Vehicle Type</label>
    <input formControlName="vtype" class="form-control ng-dirty ng-touched ng-invalid" placeholder="Type"/>
</div>

I have not found a native way to do this with Angular. I attempted to create a directive that would sync the parent div's classes with the control's validation classes, but I am unable to handle the touched event in order to set the ng-touched/ng-untouched classes on the parent element.

Any help would be greatly appreciated!

like image 985
Adam Avatar asked May 22 '17 21:05

Adam


2 Answers

<div class="form-group ng-dirty ng-touched ng-invalid" [class.ng-invalid]="myForm.vtype.invalid">
    <label for="vtype">Vehicle Type</label>
    <input formControlName="vtype" class="form-control ng-dirty ng-touched ng-invalid" placeholder="Type"/>
</div>

This help you to apply dynamic classes.

like image 91
Tejal Avatar answered Nov 03 '22 19:11

Tejal


I see this is an old question, but the answer can be useful.

Create custom directive and use HostBinding:

    import { ContentChild, Directive, ElementRef, HostBinding } from '@angular/core';
    import { FormControlName } from '@angular/forms';
    
    @Directive({
        selector: 'div.form-group'
    })
    export class ParentElementValidatorDirective {
        @ContentChild(FormControlName) controlName: FormControlName;
        @HostBinding('class.ng-invalid') get invalid() { return this.controlName.invalid && this.controlName.touched; }
        @HostBinding('class.ng-valid') get valid() { return this.controlName.valid && this.controlName.touched; }
        constructor(element: ElementRef) { }
    }

Note the selector of the directive!

like image 1
Miri Gold Avatar answered Nov 03 '22 20:11

Miri Gold