1

According to my UI the situation is totally different from this question

How to Submit the form in stepper

My scenario is that I have to create one stepper with multiple forms. So that. I have assigned each form into the individual components. And, My Button should be in the stepper component, that is only one for every form Component. Whenever I submit a form I will click the stepper submit button, which will save the form. Therefore, I used EventEmitter to catch the ngSumbit from the stepper component. But it's giving me the error that ngSubmit is undefined. My parent.stepper.component.html is

<hr>
<div fxLayout="row" fxLayoutGap="70vw">
<button (click)="child1Form.ngSubmit.emit();child2Form.ngSubmit.emit();child3Form.ngSubmit.emit()"  type="submit" mat-raised-button class="btn-submit">Save</button>
</div>
<hr>  
<mat-horizontal-stepper #stepper>
  <mat-step [stepControl]="firstFormGroup" >
      <ng-template matStepLabel>Child1</ng-template>
      <app-child1-form></app-child1-form>
      <div>
          <button mat-button matStepperNext>Next</button>
      </div>
  </mat-step>
  <mat-step [stepControl]="secondFormGroup">
      <ng-template matStepLabel>Child2</ng-template>
      <app-child2-form></app-child2-form>
      <div fxLayout="row" fxLayoutGap="70vw">
          <button mat-button matStepperPrevious>Back</button>
          <button mat-button matStepperNext>Next</button>
        </div>
  </mat-step>
  <mat-step>
      <ng-template matStepLabel>Child3</ng-template>
      <app-child3-form></app-child3-form>
      <div fxLayout="row" fxLayoutGap="70vw">
          <button mat-button matStepperPrevious>Back</button>
          <button mat-button matStepperNext>Next</button>
        </div>
  </mat-step>
  <mat-step>
      <ng-template matStepLabel>Done</ng-template>
      You are now done.
      <div>
          <button mat-button matStepperPrevious>Back</button>
          <button mat-button (click)="stepper.reset()">Reset</button>
      </div>
  </mat-step>
</mat-horizontal-stepper>

This is my parent Component. And Child belongs to all form. Like

<app-child1-form> </app-child1-form>
<app-child2-form> </app-child2-form>
<app-child3-form> </app-child3-form>

And Parrent Stepper Component, I am using the up above one Save button for submitting the child's From by using ngSubmit.emit() this is the button

<button (click)="child1Form.ngSubmit.emit();child2Form.ngSubmit.emit();child3Form.ngSubmit.emit()"  type="submit" mat-raised-button class="btn-submit">Save</button>

And one of my child's form looks like child1form.component.html

<form #child1Form="ngForm" fxLayout="row wrap" [formGroup]="firstFormGroup" fxLayoutGap="10px" (ngSubmit)="saveChild1Form()" fxLayoutAlign="center baseline">
  <mat-card-content fxLayout="column">
    <!-- Activity -->
    <mat-form-field appearance="outline">
      <mat-label>Description </mat-label>
      <textarea  required matInput formControlName="firstCtrl"  ng-trim="false" ></textarea>
    </mat-form-field>
  </mat-card-content>
</form>

The child1.component.ts file is

import { Component, OnInit, Output, EventEmitter, Input, ViewChild } from '@angular/core';
import { FormGroup, FormBuilder, NgForm, FormGroupDirective } from '@angular/forms';

@Component({
  selector: 'app-child1-form',
  templateUrl: './child1-form.component.html',
  styleUrls: ['./child1-form.component.css']
})
export class Child1FormComponent implements OnInit {

  firstFormGroup: FormGroup;
 @Output() child1Form: EventEmitter<any> = new EventEmitter<any>();
  constructor(private _formBuilder: FormBuilder) { }

  ngOnInit() {
    this.firstFormGroup = this._formBuilder.group({
      firstCtrl: [''],
      secondtCtrl: ['']
    });
  }

  saveChild1Form() {
    console.log(this.firstFormGroup.value);
  }

}

All Child forms are similar. So I didn't write here other child components. My issue is whenever I click the save button from parent.stepper.component.html, It's giving the error that ngSubmit is undefined. Could anyone please mentor me to solve this issue?

Thanks

Community
  • 1
  • 1
Riyad
  • 339
  • 4
  • 10

1 Answers1

2

Try to make use of ng-content in your template like

Your child components templates should be <ng-content></ng-content>

And in your parent component

...
<app-child1-form>
 <form [formGroup]="first">
  <label for="firstname">First name </label>
  <input type="text" formControlName="firstname">
</form>
</app-child1-form>
...
<app-child2-form>
<form [formGroup]="second">
 <label for="firstname">Middle name </label>
 <input type="text" formControlName="middlename">
</form>
</app-child2-form>
...
<app-child3-form>
 <form [formGroup]="third">
 <label for="firstname">Last name </label>
 <input type="text" formControlName="lastname">
</form>
</app-child3-form>
...

<button type="submit" (click)="save()">Submit</button>

And in your component

import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';

  constructor(private fb: FormBuilder) { 
  this.first = this.fb.group({
    firstname: ['', Validators.required]
  })
  this.second = this.fb.group({
    middlename: ['', Validators.required]
  })
  this.third = this.fb.group({
    lastname: ['', Validators.required]
  })
}

And your save method should look

save() {
  if(this.first.valid) { // or you should have the condition based on your requirement
    console.log(this.first.value)
  } else if(this.second.valid) {
     console.log(this.second.value)
  } else if(this.third.valid) {
    console.log(this.third.value)
  } else {
    return;
  }
}

Hope this might help you

Suryan
  • 701
  • 7
  • 17