David
David

Reputation: 609

Dynamically apply classes to angular custom form component

I have a custom form component and I would to dynamically apply classes to it.

import { Component, forwardRef, Injector } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { BaseInput } from './base-input';

@Component({
  selector: 'app-text-control',
  providers: [{
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => TextControlComponent),
    multi: true
  }],
  styles: [':host { display: inline-block }'],
  template: `
    <ng-container *ngIf="ctx.isEditing">    
    <input class="form-control"
    [value]="value"
    (change)="value=$event.target.value" (keyup)="value=$event.target.value" >
    </ng-container>
    <ng-container *ngIf="!ctx.isEditing">    
    {{value}}
    </ng-container>
  `
})
export class TextControlComponent extends BaseInput<string> implements ControlValueAccessor {
  constructor(injector: Injector) {
    super(injector);
  }
}

The problem is that when I apply bootstrap classes to the component in the html the container gets the classes applied and not the child html element

 <app-text-control formControlName="test" [ngClass]="{
        'is-valid' : test.valid && (test.dirty || test.touched)  ,
        'is-invalid' : test.invalid && (test.dirty || test.touched)  
      }" ></app-text-control>

class is-valid or is-invalid is applied to the app-text-control container html and not the inner input control. Is there a way to propogate the ng-class classes that are set in the parent to the child html?

I want to be able to dynamically attach classes to the html on the control inside my custom component, ideally using ngClass directive if possible. Do I have to write a custom attribute (e.g.[myNgClass]=.... )for this to work on my parent custom form control?

Upvotes: 3

Views: 2216

Answers (1)

Air1
Air1

Reputation: 567

Not sure this is the best way to do it, but you could do it this way :

<app-text-control formControlName="test" [isvalid]="test.valid && (test.dirty || test.touched)" [isinvalid]="test.invalid && (test.dirty || test.touched)" ></app-text-control>

And inside the child component you would have these isvalid and isinvalid properties which you can use with ngClass.

Upvotes: 1

Related Questions