I have a custom app-input
component which uses mat-form-field
and mat-error
but the error is not showing up.
Am I assigning the NgControl
to the formfield
the right way?
component
import { Component, OnInit, Input, forwardRef, HostListener, Self, Optional, AfterViewInit } from '@angular/core';
import { ControlValueAccessor, FormControl, FormGroup, FormGroupDirective, NgControl, NgForm, NG_VALUE_ACCESSOR } from '@angular/forms';
import { ErrorStateMatcher } from '@angular/material/core';
import { MatFormFieldAppearance, MAT_FORM_FIELD_DEFAULT_OPTIONS } from '@angular/material/form-field';
import { distinctUntilChanged } from 'rxjs/operators';
@Component({
selector: 'app-input',
templateUrl: './input.component.html',
styleUrls: ['./input.component.scss'],
})
export class InputComponent implements OnInit, ControlValueAccessor {
public formField: FormControl = new FormControl('');
@Input()
public label: string;
public value: string;
public onChanged: (value: string) => void;
public onTouched: () => void;
public isDisabled: boolean = false;
public appearance: MatFormFieldAppearance = this.isDisabled ? 'outline' : 'standard';
constructor(@Optional() @Self() public ngControl: NgControl) {
if (this.ngControl != null) {
this.ngControl.valueAccessor = this;
}
}
ngOnInit() {
const validators = this.ngControl?.control?.validator;
console.info('validators');
console.info(validators);
console.info(validators ? validators : null);
this.formField.setValidators(validators ? validators : null);
this.formField.updateValueAndValidity();
}
writeValue(value: string): void {
this.value = value;
this.formField.patchValue(value);
}
public onChange (event: Event): void {
const value: string =
(<HTMLInputElement>event.target).value;
this.onChanged(value);
}
registerOnChange(fn: any): void {
this.onChanged = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
console.info('this.isDisabled');
console.info(this.isDisabled);
if (this.isDisabled) {
this.appearance = "outline";
this.formField.reset({value: this.formField.value, disabled: true})
} else {
this.appearance = "standard";
this.formField.reset({value: this.formField.value, disabled: false})
}
}
}
template
<mat-form-field [appearance]="appearance" class="example-full-width">
<mat-label>
{{label}}
</mat-label>
<input type="text" matInput
autocomplete="off"
[value]="value"
isDisabled="true"
(input)="onChange($event)"
(blur)="onTouched()"
[formControl]="formField">
<mat-error *ngIf="formField.errors?.required">
This field is <strong>required</strong>
</mat-error>
<mat-error *ngIf="formField.errors?.email">
This email is <strong>not valid</strong>
</mat-error>
</mat-form-field>
</div>