Skip to content

feat(forms): add ability to reset forms #9974

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

Merged
merged 1 commit into from
Jul 12, 2016
Merged

feat(forms): add ability to reset forms #9974

merged 1 commit into from
Jul 12, 2016

Conversation

kara
Copy link
Contributor

@kara kara commented Jul 11, 2016

This PR adds the ability to reset forms programmatically. Calling reset() at any level will:

  • Mark the control and any child controls as pristine
  • Mark the control and any child controls as untouched
  • Set the value of control and child controls to custom value (if provided) or null
  • Update value/validity/errors of affected parties

Usage

@Component({
   selector: 'my-comp',
   template: '
      <div [formGroup]="form">
         <input formControlName="first">
         <input formControlName="last">
      </div>
   '
})
class MyComp {
   form = new FormGroup({
      first: new FormControl('Nancy'),
      last: new FormControl('Drew')
   });
}

   reset() {
      this.form.reset();  // will reset to null
     // this.form.reset({first: 'Nancy', last: 'Drew'});   -- will reset to value specified
   }

You can also call markAsPristine() or markAsUntouched() individually at any level if you'd like more fine-tuned control.

This PR also ensures that native reset buttons reset the form automatically. In other words, clicking the following button will reset all your form fields to null in both the UI and in your model:

<button type="reset">RESET</button>

@kara kara force-pushed the reset branch 4 times, most recently from c37f2d4 to 13e34b2 Compare July 11, 2016 23:34
@kara kara added action: review The PR is still awaiting reviews from at least one requested reviewer and removed state: WIP labels Jul 11, 2016
@kara kara force-pushed the reset branch 2 times, most recently from eb5d218 to 822f8c6 Compare July 12, 2016 20:31
@kara
Copy link
Contributor Author

kara commented Jul 12, 2016

@vkniazeu, this PR isn't the right place to report an issue with the docs examples. Please file an issue here: https://github.com/angular/angular.io.

@@ -48,4 +48,8 @@ export abstract class AbstractControlDirective {
}

get path(): string[] { return null; }

reset(value?: any): void {
Copy link
Contributor

@vsavkin vsavkin Jul 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though it doesn't matter, I think the intent is clearer when you use reset(value: any = undefined). The reason is you always use the value, the value is not optional. It is just you use 'default' when the value is not provided.

Also, I thought you were going to default to null, not to undefined.

@vsavkin vsavkin added pr_state: LGTM and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Jul 12, 2016
@kara kara merged commit da8eb9f into angular:master Jul 12, 2016
@iorlas
Copy link

iorlas commented Jul 13, 2016

Hoooraaay! 🍻

@robinkedia
Copy link

Hi - Can we have the documentation updated on how to reset using new forms? Do we have to use formgroup to reset pristine state?

@DeusProx
Copy link

DeusProx commented Sep 6, 2016

Hey, I don't know if I should open a new issue with a feature request for the following but I think it would be good to first talk about my idea here:

  1. We set default values when creating the FormGroup so in my opinion the "pristine" state would be the state when each of our default values is set. So reset() should set the defaults values otherwise it would be just easier to just don't specify default values at all and afterwards set them with reset({first: 'Nancy', last: 'Drew'})
  2. I also think that it is a bit confusing to use reset({first: 'Nancy', last: 'Drew'}); to set values... As I said "I set values" so it's a setter function not a reset function.

So in my opnion the following changes would be the best:

form = new FormGroup({
   first: new FormControl('Nancy'),
   last: new FormControl('Drew')
});
...
this.form.reset(); // resets to default values e.g. {first: 'Nancy', last: 'Drew'}
this.form.resetToNull(); // resets to null e.g. {first: '', last: ''}
this.form.resetAndSetValue({first: 'James'}); // resets to the specified value e.g. {first:'James', last:''}

We can argue about naming or even different changes but atm it's just counterintuitive.

@kara
Copy link
Contributor Author

kara commented Sep 7, 2016

@DeusProx To give you some background, the reset() function is intended to mimic the functionality of a native reset button. In HTML5 forms, when you reset a form, it simply empties all the values and it doesn't reset to any default value. This is how our default behavior works as well.

When you call reset() with an argument, you're actually resetting to a certain state, not just to a value. Every property of a form control can be calculated except two parts: the value and whether or not the control is disabled. Consequently, you can pass both these properties in when setting an initial state (when you instantiate a FormControl instance) or resetting to a certain state (with reset()).

So you can also do this:

this.form.reset({
   first: {value: 'Carson', disabled: true}
   last: {value: 'Drew', disabled: false}
})

Also keep in mind that what you're suggesting would be a significant breaking change for users. I'd like to avoid breaking applications unless there's a compelling reason, and in this case, I think the existing behavior that mimics native forms makes more sense.

That said, I can see where you're coming from and we always appreciate the feedback.

@DeusProx
Copy link

DeusProx commented Sep 7, 2016

@kara I understand your reasoning. Especially that you want to mimic a native reset button and use a common naming scheme. I surely can agree on that after your post! Still one should think about a functionality to fill in the default values automatically which we defined in the formgroup/formbuilder otherwise I don't even see a reason why we should specify them from the start.

We could alternatively just specify the form and it's validators in the first step and then write a function which uses this.form.reset({...}) on ngOnInit to fill in the data and reuse this function everytime we need to reset the data... I mean most of the times we want to provide the same initial value for every run through the form, won't we?
It's just some weird kind of boilerplate if we need to code the same behaviour two times in different ways to achieve the same result.

@zoechi
Copy link
Contributor

zoechi commented Sep 10, 2016

@DeusProx If you move the code that creates the FormGroup to a method, you can just recreate the FormGroup in it's default state (supported added in RC.6 or with the next update)

@DeusProx
Copy link

@zoechi I know that. i recently read in another issue that this was the "common version" of a reset in earlier versions. I also thought of this but is this really a good solution? I don't know about any side effects or performance problems. Could there be problems?

@zoechi
Copy link
Contributor

zoechi commented Sep 12, 2016

@DeusProx

or performance problems.

How many times per second do you plan to reset the form? ;-)
I wouldn't expect side effects or performance problems

@laxmikanta415
Copy link

laxmikanta415 commented Oct 24, 2017

Reseting the form in simple javascript is the solution for now.

var form : HTMLFormElement = document.getElementById('id');
form.reset();

@k11k2
Copy link

k11k2 commented Jun 11, 2018

How many times per second do you plan to reset the form? ;-)
I wouldn't expect side effects or performance problems

@zoechi right now I'm facing this. We are serving <= per second a new work to user after he/she submit current work. In this situation after loading the new values our form reset 👎 .

submit(){ this.form.reset(); this.field1 = valueField1; }

Any alternative way for this ?

and even we validating only after form.submit but still validations occurred after resetting(it clearing new values but not submitting(IMO)). why it is happening ? previous work submit action still in active ? or form.reset() also calls submit function ?.

@zoechi
Copy link
Contributor

zoechi commented Jun 11, 2018

@AlwaysAbhl001 I'd suggest to create a new issue with a StackBlitz/Plunker to reproduce.
This PR is closed and any comments probably just ignored.

@k11k2
Copy link

k11k2 commented Jun 12, 2018

@zoechi here it is repro

@zoechi
Copy link
Contributor

zoechi commented Jun 12, 2018

@AlwaysAbhl001 ignoring half of my comment won't help you.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants