Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 Material Stepper mat-step nested reactive forms

Hello I have issue with dynamic stepper where I try to generate steps with form for each step. Forms comes from nested FormGroup object. Scenario goes along:

Form:

this.formGroupNested = _formBuilder.group({
      formGroup1: _formBuilder.group({
        name: new FormControl(),
        displayName: new FormControl(),
        email: new FormControl(),
        adult: new FormControl(),
        selectField: new FormControl()
      }),
      formGroup2: _formBuilder.group({
        firstName: new FormControl(),
        lastName: new FormControl()
      })
    });

stepper.html

  <mat-horizontal-stepper [linear]="isLinear" #stepperDelivery>
    <mat-step *ngFor="let step of steps" [stepControl]="step">
        <ng-template matStepLabel>Fill out your name</ng-template>
        <!-- <form [formGroup]="step">

        </form> -->
    </mat-step>
  </mat-horizontal-stepper>

I have worked form html, but structure doesnt fit to stepper. Here is working example, in [...] are controls

<form
  *ngIf="messages; else loading"  
  [formGroup]="formGroupNested"
  [connectForm]="forms">
    <div
      formGroupName="formGroup1">
      <h1>{{ messages.authentication.form.steps.one.title }}</h1>
      <uland-text-field
      [formGroup]="formGroupNested.controls.formGroup1"
      [controlName]="'name'"
      [id]="'name'"
      [label]="messages.authentication.name.label"
      [placeholder]="messages.authentication.name.placeholder"
      [isReadOnly]="false"
      ></uland-text-field>
      [...]
    </div>
    <div 
      formGroupName="formGroup2">
      <h1>{{ messages.authentication.form.steps.two.title }}</h1>
      [...]
    </div>
</form>

Do you have any ideas how to accomplish this goal? I thought about ng-template with template alias for generate steps. Regards!

EDIT: Without nested forms, my stepper looks like this, and I guess its more easy to maintenance:

  <mat-horizontal-stepper [linear]="isLinear" #stepperDelivery>
    <mat-step [stepControl]="formGroup">
        <ng-template matStepLabel>Fill out your name</ng-template>
        <cms-development-form
        [messages]="messages"
        [formGroup]="formGroupSingle">
        </cms-development-form>
    </mat-step>
  </mat-horizontal-stepper>
like image 305
Uland Nimblehoof Avatar asked Sep 07 '25 13:09

Uland Nimblehoof


1 Answers

Use FormArray to create Dynamic Forms.Also Please find implemented example in given GitHub example: You can use the reference to create your dynamic components

TS:
  form: FormArray;

ngOnInit() {
    this.formGroup = this.formBuilder.group({
      form : this.formBuilder.array([this.init2()])
    });
  }
  addItem() {
    this.form = this.formGroup.get('form') as FormArray;
    this.form.push(this.init2());
  }
  init2() {
    return this.formBuilder.group({
      blogHeading: new FormControl('', [Validators.required]),
        });
  }
HTML:
   <form [formGroup]="formGroup">
      <mat-horizontal-stepper  formArrayName="form">
      <mat-step [formGroupName]="i" *ngFor="let customerGroup of formGroup.controls.form.controls; let i = index">
        <ng-template matStepLabel>Step {{i + 1}}</ng-template>
        <mat-form-field>
            <input matInput placeholder="blogHeading" formControlName="blogHeading" required>
            <mat-error *ngIf="!(f2.blogHeading.valid && f2.blogHeading.touched)">
              Username is Required
            </mat-error>
          </mat-form-field>
                <div>
          <button mat-button  (click)="addItem()">New Page</button>
      </div>
      </mat-step>
    </mat-horizontal-stepper>
  </form>
like image 167
Shashank Gupta Avatar answered Sep 09 '25 03:09

Shashank Gupta