angularangular2-forms

Resetting a form in Angular 2 after submit


I am aware that Angular 2 currently lacks a way to easily reset a form to a pristine state. Poking around I have found a solution like the one below that resets the form fields.

It has been suggested that I need to drop the control group and create a new one to rebuild the form as pristine. I am having difficulty figuring out the best way to do this. I know I need to wrap the form building within a function but I am running into errors when doing that within the constructor.

What would be the best way to rebuild the control group to completely reset the form?

class App {

    name: Control;
    username: Control;
    email: Control;

    form: ControlGroup;

    constructor(private builder: FormBuilder) {

        this.name = new Control('', Validators.required);
        this.email = new Control('', Validators.required);
        this.username = new Control('', Validators.required);

        this.form = builder.group({
            name: this.name,
            email: this.email,
            username: this.username
        });
    }

    onSubmit(value: any): void {  
        // code that happens when form is submitted
        // then reset the form
        this.reset();
    }

    reset() {
        for (let name in this.form.controls) {
            this.form.controls[name].updateValue('');
            this.form.controls[name].setErrors(null);
        }
    }
}

Solution

  • >= RC.6

    Support resetting forms and maintain a submitted state.

    console.log(this.form.submitted);
    
    this.form.reset()
    

    or

    this.form = new FormGroup()...;
    

    importat update

    To set the Form controls to a state when the form is created, like validators, some additional measurements are necessary

    In the view part of the form (html) add an *ngIf to show or hide the form

    <form *ngIf="showForm"
    

    In the component side of the form (*.ts) do this

      showForm:boolean = true;
    
      onSubmit(value:any):void {
        this.showForm = false;
        setTimeout(() => {
        this.reset()
          this.showForm = true;
        });
      }
    

    Here is a more detailed example:

    export class CreateParkingComponent implements OnInit {
      createParkingForm: FormGroup ;
      showForm = true ;
    
      constructor(
        private formBuilder: FormBuilder,
        private parkingService: ParkingService,
        private snackBar: MatSnackBar) {
    
          this.prepareForm() ;
      }
    
      prepareForm() {
        this.createParkingForm = this.formBuilder.group({
          'name': ['', Validators.compose([Validators.required, Validators.minLength(5)])],
          'company': ['', Validators.minLength(5)],
          'city': ['', Validators.required],
          'address': ['', Validators.compose([Validators.required, Validators.minLength(10)])],
          'latitude': [''],
          'longitude': [''],
          'phone': ['', Validators.compose([Validators.required, Validators.minLength(7)])],
          'pictureUrl': [''],
          // process the 3 input values of the maxCapacity'
          'pricingText': ['', Validators.compose([Validators.required, Validators.minLength(10)])],
          'ceilingType': ['', Validators.required],
        });
      }
    
      ngOnInit() {
      }
    
    
      resetForm(form: FormGroup) {
        this.prepareForm();
      }
    
      createParkingSubmit() {
        // Hide the form while the submit is done
        this.showForm = false ;
    
        // In this case call the backend and react to the success or fail answer
    
        this.parkingService.create(p).subscribe(
          response => {
            console.log(response);
            this.snackBar.open('Parqueadero creado', 'X', {duration: 3000});
            setTimeout(() => {
              //reset the form and show it again
              this.prepareForm();
                this.showForm = true;
              });
          }
          , error => {
            console.log(error);
            this.showForm = true ;
            this.snackBar.open('ERROR: al crear Parqueadero:' + error.message);
          }
          );
      }
    }
    

    Plunker example

    original <= RC.5 Just move the code that creates the form to a method and call it again after you handled submit:

    @Component({
      selector: 'form-component',
      template: `
        <form (ngSubmit)="onSubmit($event)" [ngFormModel]="form">
           <input type="test" ngControl="name">
           <input type="test" ngControl="email">
           <input type="test" ngControl="username">
           <button type="submit">submit</button>
        </form>
        <div>name: {{name.value}}</div>
        <div>email: {{email.value}}</div>
        <div>username: {{username.value}}</div>
    `
    })
    class FormComponent {
    
      name:Control;
      username:Control;
      email:Control;
    
      form:ControlGroup;
    
      constructor(private builder:FormBuilder) {
        this.createForm();
      }
    
      createForm() {
        this.name = new Control('', Validators.required);
        this.email = new Control('', Validators.required);
        this.username = new Control('', Validators.required);
    
        this.form = this.builder.group({
          name: this.name,
          email: this.email,
          username: this.username
        });
      }
    
      onSubmit(value:any):void {
        // code that happens when form is submitted
        // then reset the form
        this.reset();
      }
    
      reset() {
        this.createForm();
      }
    }
    

    Plunker example