mat-form-field does not remove mat-form-field-invalid class on FormGroup reset
Bug, feature request, or proposal:
Bug
What is the expected behavior?
Upon resetting a FormGroup, I would expect the visual state of the form to be reset also.
What is the current behavior?
The form group and controls are reset but the mat-input-invalid class remains on the md-input-container suggesting that the control is invalid.
What are the steps to reproduce?
This only seems to happen when the [formGroup] attribute is on a form tag. Works as expected on a div tag.
Create component with a FormGroup and a FormControl with Validators.required . Create a form tag with the [formGroup] attribute. Add an input control to the form with a required attribute.
When running, fill out the form so its valid, then reset the form and model through the click handler on a button. The required control will now have the mat-input-invalid class.
Which versions of Angular, Material, OS, browsers are affected?
Angular 4.0.1 Material 2.0.0-beta.3 Windows 10 Chrome 57
Have the same issue 😢
plunker repro: http://plnkr.co/edit/UguaoP1sTR85pyZLh2TN?p=preview
It looks like this is just a matter of putting type="reset" on your button. Without it, the form is marked as submitted which causes the error styling to show up. see: http://plnkr.co/edit/IUhbPom8FnauivHUW3bU?p=preview
@mmalerba trying to understand how this would fix the issue for a button already type="submit".
I'm resetting after the form is submitted and a response has been received back from the server in an observable complete block.
i.e., submitForm() .subscribe( res => store.dispatch(type: foo, res), e => log(e), () => form.reset()); <- still leaving the form inputs as invalid
@goelinsights sounds like maybe a forms issue (could be related to https://github.com/angular/angular/issues/15741). The md-input-container logic is correct, so there's nothing for material to do here
Not sure why, using resetForm() method fixed this issue for me.
@mmalerba not sure i agree with your diagnosis. I am experiencing same issues and have only updated from material-beta2 to material-beta3. Main angular libraries remain unchanged and problem has only been introduced since material upgrade.
It looks like this is just a matter of putting type="reset" on your button. Without it, the form is marked as submitted which causes the error styling to show up.
after form is submitted, error styling should definitely be removed.
@mmalerba Why is this issue closed? The problem still exists when reseting the formGroup like explained by @goelinsights
Scenario: Press submit button Do some stuff with the data Then call formGroup.reset()
formGroup.reset() does NOT remove mat-input-invalid class

@jeroenvanagt try this
<form [formGroup]="myFormGroup" #f="ngForm">
...
</form>
@ViewChild('f') myNgForm;
reset() {
this.myNgForm.resetForm();
}
http://plnkr.co/edit/sRCiYvRqGevK493w79A4?p=preview
@willshowell,
I understand that a reset button works. However, in my case I want to use a submit button, send the data to the backend server and then reset the form (so a new invite can be created).
For the reset, I use :
this.form.reset()
where form is a formGroup
I now use the following workaround
this.form.reset()
Object.keys(this.form.controls).forEach(key => {
this.form.controls[key].setErrors(null)
});
@jeroenvanagt Error state is calculated like this:
isInvalid && (isTouched || isSubmitted)
Unfortunately, resetting the FormGroup isn't enough. You'll need to reset the submitted state of the actual form.
To do that, you need to get access to the FormGroupDirective which binds the FormGroup to the form and then call resetForm() instead of reset().
<form [formGroup]="fg">
...
</form>
@ViewChild(FormGroupDirective) myForm;
sendDataToBackendAndResetForm() {
// TODO: send data to backend
if (this.myForm) {
this.myForm.resetForm();
}
}
See this updated plunker for an example
@mmalerba I don't think we can call a workaround a resolution. This still is not fixed.
Why can't the FormGroup.reset() method use the FormGroupDirective to clear the submitted state of the form element?
@Nathan-Ryan The FormGroup and FormGroupDirective are part of angular core, not angular material. If you want to request changes to the behavior you can file an issue with https://github.com/angular/angular
@mmalerba the hacky workaround is just to manually remove .mat-input-invalid on submission. If that's the desired approach, we should put it into the docs as it's a fairly straightforward way to address what should be a common problem for a reusable form that is reset on submission (that from my perspective isn't an expected or obvious output).
On Wed, Jun 21, 2017 at 12:01 PM, mmalerba [email protected] wrote:
@Nathan-Ryan https://github.com/nathan-ryan The FormGroup and FormGroupDirective are part of angular core, not angular material. If you want to request changes to the behavior you can file an issue with https://github.com/angular/angular
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/angular/material2/issues/4190#issuecomment-310174269, or mute the thread https://github.com/notifications/unsubscribe-auth/ACv1DSsUuegP-lRLkdGOj5o1CoY8DEAUks5sGWh_gaJpZM4NDvLu .
--
Vijay Goel, M.D. Principal, Goel Insights 310-492-5601 www.goelinsights.com
@goelinsights I may be mistaken but manually removing classes is not the recommended workaround. I'll summarize here:
-
Submitted state is based on the
FormGroupDirectiveor theNgForm(depending on if you're using template- or model-driven forms).FormGroupdoes not hold submitted state. -
If you wish to reset the form, you must gain access to the
FormGroupDirectiveor theNgFormand callresetForm()on it. That will remove.mat-input-invalidfrom the input and all associatedmd-errors -
This behavior is in Angular core, not material. You are welcome to propose a change to the behavior, but that should be done in the angular core repository, not here.
-
If you simply don't want
.mat-input-invalidto depend at all on submitted state, you will be able to purpose https://github.com/angular/material2/pull/4750 for that once it lands.
Any Update on this fix?
The simplest solution isn't resetting the form afterwards, but preventing the form from being submitted in the first place. You can do that by putting a type="button" on the button element, so something like this works as expected in my project:
<button type="button" mat-raised-button (click)="form.reset()">
reset
</button>
this resolved my issue https://stackoverflow.com/questions/48216330/angular-5-formgroup-reset-doesnt-reset-validators
I think @biowaffeln's answer is the way to go. Simply avoid all references to "Submit" and you're good. To expand on his example:
Before:
<form [formGroup]="createForm" class="create-form" (ngSubmit)="submitForm()">
<button type="submit" mat-raised-button color="primary" [disabled]="createForm.pristine">Create</button>
</form>
After:
<form [formGroup]="createForm" class="create-form">
<button (click)="submitForm()" type="button" mat-raised-button color="primary" [disabled]="createForm.pristine">Create</button>
</form>
Your submit function doesn't accept any arguments, it will simply access form values via the class property, so it doesn't make a difference either way:
submitForm() {
this.myEventEmitter.emit(this.createForm.value)
}
@jplew an advantage of using (ngSubmit) on form is that the form is automatically submitted when you press Enter in a text field. You would need to do that manually.
@NaveenJayaram94 created an infinite loop
Actually this is still a bug only in material. It has nothing to do with resetting the submit state.
In angular core i can put markAsPristine and markAsUntouched on a single formControl. The css classes get set correctly ignoring if it was submitted or not.
The question is why put css class mat-form-field-invalid on it, when there is already ng-invalid. The "red-state" could be calculated like this: ng-invalid && ng-touched finish, it would work.
Bug, feature request, or proposal:
Bug
What is the expected behavior?
Upon resetting a FormGroup, I would expect the visual state of the form to be reset also.
What is the current behavior?
The form group and controls are reset but the mat-input-invalid class remains on the md-input-container suggesting that the control is invalid.
What are the steps to reproduce?
This only seems to happen when the [formGroup] attribute is on a form tag. Works as expected on a div tag.
Create component with a FormGroup and a FormControl with Validators.required . Create a form tag with the [formGroup] attribute. Add an input control to the form with a required attribute.
When running, fill out the form so its valid, then reset the form and model through the click handler on a button. The required control will now have the mat-input-invalid class.
Which versions of Angular, Material, OS, browsers are affected?
Angular 4.0.1 Material 2.0.0-beta.3 Windows 10 Chrome 57
I am also having this issue after reset the form controls are reset but mat-errors are showing invalid
There could be some change detection issue with the mat-form-field-invalid class. I'll reopen for investigation
Will the problem be solved in the next 1 - 2 releases? Since the problem already exists since 2017?
bump
I love the "not my department" attitude here. The workaround mentioned in this stackoverflow answer should be the default behavior
https://stackoverflow.com/questions/48216330/angular-5-formgroup-reset-doesnt-reset-validators
Versions: "@angular/animations": "^7.2.2", "@angular/cdk": "^7.3.2", "@angular/common": "^7.2.4", "@angular/compiler": "^7.2.4", "@angular/core": "^7.2.4", "@angular/forms": "^7.2.4", "@angular/material": "^7.3.2"
This work for me, for this scenario; I have and material stepper and the user can start de process if he likes, then before show the first step I reset de form calling form():
template:
<form [formGroup]="formGroup"> <button type="button" (click)="submitForm()">
ts:
ngOnInit() {this.formGroup = this._formBuilder.group(new MyForm()); }
submitForm() {
let control: AbstractControl = null; Object.keys(this.formGroup.controls).forEach((name) => { control = this.formGroup.controls[name]; control.updateValueAndValidity(); });
}
reset() { let control: AbstractControl = null; this.formGroup.reset(new DatosGeneralesForm());
setTimeout(() => {
this.formGroup.markAsUntouched();
Object.keys(this.formGroup.controls).forEach((name) => {
control = this.formGroup.controls[name];
control.reset();
control.setErrors(null);
});
}, 100);
}
it seems this is still an issue.
the workaround from @willshowell worked for me, but had to go through some research to get this fixed. Thinking it could be fixed with alternatives already provided here, or at least better documented.