Step wizard form

匆匆过客 提交于 2019-12-02 08:31:52

If you want to create stepper form you can project the form and use the formcontrol to connect the parentformgroup.

ParentComponent.ts


Next
<div class="step container" *ngIf="form.valid && nextForm" >
 <form [formGroup]="step2">
  <app-step2 (control)="enableSave($event)"></app-step2>
  <button class="btn btn-primary"  (click)="moveToPrevious()" >Previous</button>
</form>
</div>
<hr>
<button
[disabled]="eSave"
 class="btn btn-primary" (click)="save()">Save</button>
</app-stepper-wrapper>

ParentComponent.ts

name = 'Angular';
  eSave = true;
  form = new FormGroup({});
  step2 = new FormGroup({});
  nextForm = false;

  ngOnInit() {
    this.form.statusChanges.subscribe(s => this.eSave = true);
  }   
  moveToNext() {
    if (this.form.valid) {
      this.nextForm = true;
    }
  }   
  moveToPrevious() {
    this.nextForm = false;
  }
  save() {
    console.log(this.form);
    console.log(this.step2);
  }
  enableSave($event) {
    if ($event == 'VALID' && this.form.valid) {

      this.eSave = false;
    }
  }

Example:https://stackblitz.com/edit/angular-nynvvr

Pass array in the goBack method which you want to remove

   <button (click)="goBack('myArray')"> Previous </button> &nbsp;    

Put this method in the component ts file

  goBack(control: string) {
    let question: any = this.questions.find(q => q.key == control);
     let children = question ? question.children : null;
    if (children)

      (this.form.get(control) as FormArray).removeAt(children.length-1)

  }

Have try to reach your requirements : Except UI part. I hope you can handle you UI as your requirement.

TS :

    import { Component, Input, OnInit } from '@angular/core';
    import { FormGroup, FormArray } from '@angular/forms';

    import { QuestionBase } from './question-base';
    import { QuestionControlService } from './question-control.service';

    @Component({
      selector: 'app-dynamic-form',
      templateUrl: './dynamic-form.component.html',
      providers: [QuestionControlService]
    })
    export class DynamicFormComponent implements OnInit {

      @Input() questions: QuestionBase<any>[] = [];
      form: FormGroup;
      payLoad = '';

      page: number = 0;

      constructor(private qcs: QuestionControlService) { }

      ngOnInit() {
        this.form = this.qcs.toFormGroup(this.questions);
      }

      onSubmit() {
        this.payLoad = JSON.stringify(this.form.value);
      }
      addControls(control: string, index: any) {
        let array = this.form.get('myArray') as FormArray;
        if (array.length > this.page) {
          this.page = this.page + 1;
        } else {
          let question: any = this.questions.find(q => q.key == control);
          let children = question ? question.children : null;
          if (children)
            (this.form.get(control) as FormArray).push(this.qcs.toFormGroup(children))
          this.page = this.page + 1;
        }
      }
      removeControls(control: string) {
        let array = this.form.get(control) as FormArray;
        array.removeAt(array.length - 1);
      }

      goBack() {
        if (this.page > 0) {
          this.page = this.page - 1;
        }
        //let array = this.form.get('myArray') as FormArray;
        //array.removeAt(array.length - 1);
        //Function to move to previous step
      }

    }

HTML : 

<div>
    <form (ngSubmit)="onSubmit()" [formGroup]="form">

        <div *ngFor="let question of questions" class="form-row">
            <ng-container *ngIf="question.children">
                <div [formArrayName]="question.key">
                    <div *ngFor="let item of form.get(question.key).controls; let i=index" [formGroupName]="i">
            <ng-template [ngIf]="i + 1 == page"> 
              <div *ngFor="let item of question.children">
                <app-question [question]="item" [form]="form.get(question.key).at(i)"></app-question>
              </div>
            </ng-template>
                    </div>
                </div>
            </ng-container>
            <ng-container *ngIf="!question.children">
                <app-question [question]="question" [form]="form"></app-question>

            </ng-container>
        </div>

  <button (click)="goBack()"> Previous </button> &nbsp;
  <button (click)="addControls('myArray',i)"> Next </button> 

        <div class="form-row">
            <button type="submit" [disabled]="!form.valid">Save</button>
    </div>
  </form> <br>

  <pre>
{{form?.value|json}}
</pre>
</div>

This will help you showing one page at a time. It will create new one if no next form exists. And on clicking previous it will navigate to old form.

So, you want to remove lastly added control email and dropdown control from the form group array.

I have added the code into goBack() function to remove child form group controls.

Component:

  goBack() {
    //Function to move to previous step
    if(this.form.controls['myArray']){      
      const arr = <FormArray>this.form.controls.myArray;
      arr.removeAt(arr.length - 1);
    }
  }

Working demo: https://angular-x4a5b6-cc4kyr.stackblitz.io

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!