By default, Angular/Material watch formControl's error state not only by touched but also submitted status of the form, see below source code.
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
return !!(control && control.invalid && (control.touched || (form && form.submitted)));
^^^^^^^^^^^^^^
}
For reason above, you also need to reset the form to unsubmitted status.
You can call resetForm of FormGroupDirective(getting instance by ViewChild) for it will reset both the form data and submit status.
<form #form="ngForm" [formGroup]="checkForm" (ngSubmit)="submitForm(form)">
...
</form>
@ViewChild('form') form;
submitForm() {
this.form.resetForm();
...
}
You can also overwrite the default one via implementing ErrorStateMatcher with custom conditions such as ignore submitted status of the form, and apply it on material components.
<mat-form-field>
<input matInput formControlName="name" placeholder="name" [errorStateMatcher]="errorMatcher" />
<mat-error *ngIf="checkForm.get('name').errors?.required">
Name is required.
</mat-error>
</mat-form-field>
// define custom ErrorStateMatcher
export class CustomErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl, form: NgForm | FormGroupDirective | null) {
return control && control.invalid && control.touched;
}
}
// component code
@Component({...})
export class CustomComponent {
// create instance of custom ErrorStateMatcher
errorMatcher = new CustomErrorStateMatcher();
}
see fixed demo.
Share
Improve this answer
Follow
edited Jan 29 '19 at 3:35
answered Apr 12 '18 at 5:58
Pengyy
31.9k1515 gold badges6969 silver badges6868 bronze badges
Thanks for the solution. In the return statement of isErrorState(), both touch and form submitted are connected by "or" operator so only one of them need to be true at one point of time. I think builtIn function "checkForm.reset()" internally untouched, pristine all the fields. – Ajay Apr 12 '18 at 7:54
1
@Ajay Mention expression (control.touched || (form && form.submitted), either touched or form submitted will turn above expression to true. – Pengyy Apr 12 '18 at 8:19
I am facing issues with above code. It show fields after focussing on them. Any hint would be helpful. – Ajay Apr 17 '18 at 4:03
Fields are hidden in starting(similar to invisible). Shown only when user focusses on them. – Ajay Apr 17 '18 at 4:23
@Ajay I didn't see it in the demo I provided. Maybe you forgot to set placeholder for them? – Pengyy Apr 17 '18 at 4:35
Show 5 more comments
16
All you need to do is avoid (ngSubmit) method on your reactive form:
1. Remove (ngSubmit)="submitForm()" from your form tag
1. Change your form button type from 'submit' to 'button'
2. On this button you want to set a click action to (click)="submitForm()"
3. in the submitForm() method do:
this.checkForm.markAsPristine();
this.checkForm.markAsUntouched();
This will submit the form and reset its value without alerting validators