Skip to content
This repository has been archived by the owner on Apr 13, 2022. It is now read-only.

ngForm stays $dirty after control.$setPristine() #13715

Closed
jar240 opened this issue Jan 8, 2016 · 7 comments · May be fixed by #13773
Closed

ngForm stays $dirty after control.$setPristine() #13715

jar240 opened this issue Jan 8, 2016 · 7 comments · May be fixed by #13773

Comments

@jar240
Copy link

jar240 commented Jan 8, 2016

Hi there. Frustrating problem. in an ngForm, if in my controller I set one of the form's controls to $dirty (via control.$setDirty()), then in the controller set the same control to $pristine, the form remains $dirty.

  1. on state load, form is $pristine
  2. via another event, call controller function that does control.$setDirty() - form is now $dirty
  3. via another event, call controller function that does control.$setPristine() - form is still $dirty

I'm pretty sure this shouldn't happen, and is getting kludgy to fix. I'm using Angular 1.4.8.

Plunkr:
https://plnkr.co/edit/6noEtj6vbMkqxiKK6Yp7?p=preview

Thanks

@gkalpak
Copy link
Member

gkalpak commented Jan 9, 2016

I'm pretty sure this is how it is supposed to work. ngForm does not keep track of which controls are pristine/dirty. Setting a control to $dirty will propagation the "dirty-ness" to the parent form controllers, but setting all controls to $pristine will not set the parent form(s) to $pristine as well.

It's not an unreasonable feature to request, but it would add a tiny bit of overhead (which won't be necessary for most apps).

If you need such functionality, you can always implement a work-around.
In any case, this will be much easier if/when we expose the controls array.

@Narretz, do you think it is reasonable to check if all controls are $pristine (whenever a control is set to $pristine) and set the parent form to $pristine too (if all controls are $pristine) ?

@Narretz
Copy link
Contributor

Narretz commented Jan 11, 2016

User expectation is probably that the form is set to $pristine, and I can see how that makes sense. We have the same problem with $setValidity, too, afaik.
I'm not to keen about implementing this logic. A parent form form would potentially need to loop through hundreds of children to determine its pristine-ness.
Either we make this check available behind a flag, or we expose the child forms / child controls on the form element, so that developers can loop over them themselves.

@Narretz Narretz added this to the Ice Box milestone Jan 11, 2016
linoleum-js added a commit to linoleum-js/angular.js that referenced this issue Jan 15, 2016
When calling $setPristine on the nested form or control,
form becomes $pristine of all the nested controls are pristine

Closes angular#13715
@linoleum-js
Copy link

I wrote some brute force solution, but.. what if we will keep track of number of nested pristine controls/forms? 0 by default, it will be increased in $setPristin and decreased in $setDirty. By comparing it each time with controls.length we will get $pristine. I'm not sure what should happen when we add/remove controls, but i guess it can be solved too.

@gkalpak
Copy link
Member

gkalpak commented Jan 15, 2016

Having an internal counter also seems like a viable solution. I can't think of a corner case that could not be handled with such an implementation (if implemented properly).

@jar240
Copy link
Author

jar240 commented Jan 15, 2016

Hi, thanks for considering this.

I understand that revalidating the entire form to check for $pristine is a an inexpensive operation relative to setting the form to $dirty when a single control is set dirty. I like the idea of counters for the $touched, $untouched, $pristine and $dirty status of each field, since we only care whether or not the counter is 0 each.

linoleum-js added a commit to linoleum-js/angular.js that referenced this issue Jan 19, 2016
…Pristine() (brute force version)

When calling $setPristine on the nested form or control,
form becomes $pristine of all the nested controls are pristine

Closes angular#13715
linoleum-js added a commit to linoleum-js/angular.js that referenced this issue Jan 19, 2016
…(brute force version)

When calling $setPristine on the nested form or control,
form becomes $pristine of all the nested controls are pristine

Closes angular#13715
@adamreisnz
Copy link

I take it this issue has never been resolved, and probably won't be?

@Narretz
Copy link
Contributor

Narretz commented Jul 29, 2019

@adamreisnz That's correct. It should be possible to implement this logic by using https://docs.angularjs.org/api/ng/type/form.FormController#$getControls and a custom $setPristine implementation.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
5 participants