Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mat-form-field does not remove mat-form-field-invalid class on FormGroup reset #4190

Open
Nathan-Ryan opened this Issue Apr 21, 2017 · 33 comments

Comments

Projects
None yet
@Nathan-Ryan
Copy link

Nathan-Ryan commented Apr 21, 2017

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

@Nathan-Ryan Nathan-Ryan changed the title md-input-container does not remove mat-input-invalid class on FromGroup reset md-input-container does not remove mat-input-invalid class on FormGroup reset Apr 21, 2017

@kurpav

This comment has been minimized.

Copy link

kurpav commented Apr 22, 2017

Have the same issue 😢

@mmalerba mmalerba self-assigned this Apr 26, 2017

@mmalerba mmalerba added the P3 label Apr 26, 2017

@mmalerba

This comment has been minimized.

Copy link
Contributor

mmalerba commented May 10, 2017

@mmalerba

This comment has been minimized.

Copy link
Contributor

mmalerba commented May 11, 2017

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 mmalerba closed this May 11, 2017

@goelinsights

This comment has been minimized.

Copy link

goelinsights commented May 12, 2017

@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

@mmalerba

This comment has been minimized.

Copy link
Contributor

mmalerba commented May 12, 2017

@goelinsights sounds like maybe a forms issue (could be related to angular/angular#15741). The md-input-container logic is correct, so there's nothing for material to do here

@rajvengala

This comment has been minimized.

Copy link

rajvengala commented May 12, 2017

Not sure why, using resetForm() method fixed this issue for me.

@zpydee

This comment has been minimized.

Copy link

zpydee commented May 13, 2017

@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.

@jeroenvanagt

This comment has been minimized.

Copy link

jeroenvanagt commented May 30, 2017

@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
screen shot 2017-05-30 at 4 06 33 pm

@willshowell

This comment has been minimized.

Copy link
Contributor

willshowell commented May 30, 2017

@jeroenvanagt try this

<form [formGroup]="myFormGroup" #f="ngForm">
  ...
</form>
@ViewChild('f') myNgForm;

reset() {
  this.myNgForm.resetForm();
}

http://plnkr.co/edit/sRCiYvRqGevK493w79A4?p=preview

@jeroenvanagt

This comment has been minimized.

Copy link

jeroenvanagt commented May 31, 2017

@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

@jeroenvanagt

This comment has been minimized.

Copy link

jeroenvanagt commented May 31, 2017

I now use the following workaround

        this.form.reset()

        Object.keys(this.form.controls).forEach(key => {
          this.form.controls[key].setErrors(null)
        });

@willshowell

This comment has been minimized.

Copy link
Contributor

willshowell commented May 31, 2017

@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

@Nathan-Ryan

This comment has been minimized.

Copy link
Author

Nathan-Ryan commented Jun 16, 2017

@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?

@mmalerba

This comment has been minimized.

Copy link
Contributor

mmalerba commented Jun 21, 2017

@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

@goelinsights

This comment has been minimized.

Copy link

goelinsights commented Jun 27, 2017

@willshowell

This comment has been minimized.

Copy link
Contributor

willshowell commented Jun 27, 2017

@goelinsights I may be mistaken but manually removing classes is not the recommended workaround. I'll summarize here:

  1. Submitted state is based on the FormGroupDirective or the NgForm (depending on if you're using template- or model-driven forms). FormGroup does not hold submitted state.

  2. If you wish to reset the form, you must gain access to the FormGroupDirective or the NgForm and call resetForm() on it. That will remove .mat-input-invalid from the input and all associated md-errors

  3. 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.

  4. If you simply don't want .mat-input-invalid to depend at all on submitted state, you will be able to purpose #4750 for that once it lands.

@gersonpineda

This comment has been minimized.

Copy link

gersonpineda commented Nov 21, 2017

Any Update on this fix?

@biowaffeln

This comment has been minimized.

Copy link

biowaffeln commented Nov 28, 2017

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>
@NaveenJayaram94

This comment has been minimized.

@Ldhatter Ldhatter referenced this issue Mar 27, 2018

Closed

Form Polishing 🤖 #99

12 of 12 tasks complete
@jplew

This comment has been minimized.

Copy link

jplew commented May 15, 2018

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)
}
@ondrejpar

This comment has been minimized.

Copy link

ondrejpar commented Jun 20, 2018

@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.

@chachan

This comment has been minimized.

Copy link

chachan commented Aug 29, 2018

@NaveenJayaram94 created an infinite loop

@nickwinger

This comment has been minimized.

Copy link

nickwinger commented Nov 27, 2018

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.

@krmgopi

This comment has been minimized.

Copy link

krmgopi commented Dec 3, 2018

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

@mmalerba

This comment has been minimized.

Copy link
Contributor

mmalerba commented Dec 3, 2018

There could be some change detection issue with the mat-form-field-invalid class. I'll reopen for investigation

@mmalerba mmalerba reopened this Dec 3, 2018

@mmalerba mmalerba changed the title md-input-container does not remove mat-input-invalid class on FormGroup reset mat-form-field does not remove mat-form-field-invalid class on FormGroup reset Dec 3, 2018

@cschoeni

This comment has been minimized.

Copy link

cschoeni commented Jan 30, 2019

Will the problem be solved in the next 1 - 2 releases? Since the problem already exists since 2017?

@eugensunic

This comment has been minimized.

Copy link

eugensunic commented Jan 31, 2019

bump

@ctilley83

This comment has been minimized.

Copy link

ctilley83 commented Feb 2, 2019

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

@ccamba

This comment has been minimized.

Copy link

ccamba commented Feb 28, 2019

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);

}

@bruno-kremer

This comment has been minimized.

Copy link

bruno-kremer commented Mar 11, 2019

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.

@emadkheiralla

This comment has been minimized.

Copy link

emadkheiralla commented Apr 2, 2019

I now use the following workaround

        this.form.reset()

        Object.keys(this.form.controls).forEach(key => {
          this.form.controls[key].setErrors(null)
        });

This worked for me. Thanks

@MatthiasKunnen

This comment has been minimized.

Copy link

MatthiasKunnen commented Apr 3, 2019

@emadkheiralla, while that works for a 1 level structure, it won't work for nested controls. You would need to create a recursive function for that. It also is not recommended, see #4190 (comment).

@alexandrebeato

This comment has been minimized.

Copy link

alexandrebeato commented Apr 16, 2019

Same problem here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.