angularangular-material-stepper

Angular - Material Stepper Skips one step on Next Step Click


In Angular-12 I am implementing Material Stepper:

@ViewChild('stepper') stepper!: MatHorizontalStepper;
isLinear = true; 
districtInfoForm!: FormGroup;
zonalInfoForm!: FormGroup;
groupInfoForm!: FormGroup;
regionInfoForm!: FormGroup;
stateInfoForm!: FormGroup;
countryInfoForm!: FormGroup;

ngOnInit() {
  this.createEmployee();
}

districtNext() {
  if (!this.districtInfoForm.valid) {
    this.districtInfoForm.markAllAsTouched();
    return;
  }
  this.stepper.next();
}

zonalNext() {
  if (!this.zonalInfoForm.valid) {
    this.zonalInfoForm.markAllAsTouched();
    return;
  }
  this.stepper.next();
}

groupNext() {
  if (!this.groupInfoForm.valid) {
    this.groupInfoForm.markAllAsTouched();
    return;
  }
  this.stepper.next();
}

regionNext() {
  if (!this.regionInfoForm.valid) {
    this.regionInfoForm.markAllAsTouched();
    return;
  }
  this.stepper.next();
}

stateNext() {
  if (!this.stateInfoForm.valid) {
    this.stateInfoForm.markAllAsTouched();
    return;
  }
  this.stepper.next();
}

countryNext() {
  if (!this.countryInfoForm.valid) {
    this.countryInfoForm.markAllAsTouched();
    return;
  }
  this.stepper.next();
}

HTML

<div class="card-body">
  <mat-horizontal-stepper [linear]="isLinear" #stepper labelPosition="bottom">
    <mat-step [stepControl]="districtInfoForm">
      <ng-template matStepLabel>District</ng-template>
      <form>

        <div class="card-footer">
          <button mat-raised-button color="primary" matStepperNext (click)="districtNext()">Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step [stepControl]="zonalInfoForm">
      <ng-template matStepLabel>Zonal Info</ng-template>
      <form>

        <div class="card-footer">
          <button mat-raised-button color="black" matStepperPrevious>Back</button>&nbsp;
          <button mat-raised-button color="primary" matStepperNext (click)="zonalNext()">Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step [stepControl]="groupInfoForm">
      <ng-template matStepLabel>Group Info</ng-template>
      <form>

        <div class="card-footer">
          <button mat-raised-button color="black" matStepperPrevious>Back</button>&nbsp;
          <button mat-raised-button color="primary" matStepperNext (click)="groupNext()">Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step [stepControl]="regionInfoForm">
      <ng-template matStepLabel>Region Details</ng-template>
      <form>

        <div class="card-footer">
          <button mat-raised-button color="black" matStepperPrevious>Back</button>&nbsp;
          <button mat-raised-button color="primary" matStepperNext (click)="regionNext()">Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step [stepControl]="stateInfoForm">
      <ng-template matStepLabel>State Details</ng-template>
      <form>

        <div class="card-footer">
          <button mat-raised-button color="black" matStepperPrevious>Back</button>&nbsp;
          <button mat-raised-button color="primary" matStepperNext (click)="stateNext()">Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step [stepControl]="countryInfoForm">
      <ng-template matStepLabel>Country History</ng-template>
      <form>
        <div class="row">
          <div class="col-md-12">
            <div class="row">

            </div>
          </div>
        </div>
        <div class="card-footer">
          <button mat-raised-button color="black" matStepperPrevious>Back</button>&nbsp;
          <button mat-raised-button color="primary" matStepperNext (click)="countryNext()">Next</button>
        </div>
      </form>
    </mat-step>
    <mat-step>
      <ng-template matStepLabel>Review</ng-template>
      <h5 style="color:blue;">You are now done.</h5>
      <hr>

    </mat-step>

  </mat-horizontal-stepper>
</div>

When the form controls are there it skips only the first step. That is, from District to Group. Then I removed the form controls, it skips one step on each click Distict -> Group -> State -> Review

But the back button is not like that.

What could have caused this and how do I resolve it?

Thanks


Solution

  • It's becouse matStepperNext attribute on your button for next. This attribute is emmiting .next() function on stepper by itself, and your doing it second time inside your (click) functions.

    Remove this.stepper.next() from functions:

    also i would suggest to change all those methods to one:

    nextValidation(form: FormGroup) {
      if (!form.valid) {
        form.markAllAsTouched();
        return;
      }
    }
    

    and pass specific FormGroup in html;