I've got a reactive form with nested formgroups with some form controls that have required validators.
It seems the validation only occurs when a user inputs values into the form. If the form is submitted with no user interaction, empty textboxes with a required validator show as valid. Is this a normal behavior of angular forms? Am I missing something?
Thanks
Pete
html template:
<form [formGroup]="ticketMarkForm" (ngSubmit)="submitTicket()">
..
<div formGroupName ="systemForm">
<mat-form-field appearance="outline">
<mat-label>Pipe Length (Ft):</mat-label>
<input matInput type="number" required formControlName="pipeLength">
</mat-form-field>
</div>
..
<button type="submit" mat-stroked-button>Submit</button>
</form>
component typescript:
export class MtMarkFormComponent implements OnInit {
..
ticketMarkForm: FormGroup;
...
constructor(private checkService: MTMarkFormCheckService) { }
ngOnInit(): void {
//forms
this.ticketMarkForm = new FormGroup({
systemForm: new FormGroup({
...
pipeDiameter: new FormControl(Validators.required),
...
})
});
}
submitTicket() {
let pipeDiam:any=this.ticketMarkForm.get('systemForm').get('pipeDiameter');
this.checkService.CheckRequiredValid(pipeDiam);
}
}
Service to check form typescript:
export class MTMarkFormCheckService {
CheckRequiredValid(fc: FormControl) {
if (fc.invalid) {//if the control is left blank/untouched evaluates to valid. I've also
tried to mark the control as dirty (fc.markAsDirty()) but same result
alert("invalid");
}
else {
alert("valid");
}
}
It is default Angular behavior. You have to define custom error state matcher like this.
import {FormControl, FormGroupDirective, NgForm} from '@angular/forms';
import {ErrorStateMatcher} from '@angular/material/core';
export class CustomErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null | undefined, form: FormGroupDirective | NgForm | null): boolean {
if (control == null) {
return false;
}
return control.invalid;
}
}
ts :
export class MtMarkFormComponent implements OnInit {
:
public esm = new CustomErrorStateMatcher();
:
}
html :
<input matInput type="number" required formControlName="pipeLength" [errorStateMatcher]="esm">