3

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>
Uland Nimblehoof
  • 862
  • 17
  • 38
  • is your problem about displaying the right formGroup in each step? – Gérôme Grignon Dec 28 '18 at 13:58
  • Just wondering should I use simple reactive forms for each step, or can I use complete nested reactive form. With big nested forms there is problem with html, because there is only one
    tag and it's not fit to stepper structure, which predicting new form for each step.
    – Uland Nimblehoof Dec 28 '18 at 14:53

1 Answers1

1

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>