Search code examples
angularangular-materialmat-stepper

Mat-stepper next button inside table needs double click Angular


I am trying to make the rows of a table to be next steppers for a mat-stepper. The problem is that the buttons need to be double-clicked in order to be selected. I am including my code below

<mat-stepper linear #stepper>
  <mat-step [completed]="firstStep">
    <ng-template matStepLabel>Pick a folder</ng-template>
    <table mat-table [dataSource]="folders">
      <ng-container matColumnDef="folder">
        <mat-header-cell *matHeaderCellDef>Folders.</mat-header-cell>
        <mat-cell *matCellDef="let folder">
          <button mat-button matStepperNext (click)="pickCorrectFolder(folder)">
            {{ folder }}
          </button></mat-cell
        >
      </ng-container>
      <mat-header-row
        *matHeaderRowDef="folderCol"
      ></mat-header-row>
      <mat-row *matRowDef="let myRowData; columns: folderCol"> </mat-row>
    </table>
  </mat-step>

I want to only click once to move to the next step. Does anyone know why this is happening and how can i fix it ?


Solution

  • Solution

    Call stepper.next() in your logFolderRowData method instead of using matStepperNext directive after you set the firstStep to true.

    In your Template:

    <button mat-button (click)="logFolderRowData(folder, stepper)">
        {{ folder }}
    </button>
    

    In your Component:

      constructor(private cdRef: ChangeDetectorRef) {}
      logFolderRowData(row: any, stepper: MatStepper) {
        this.pickCorrectFolder(row, stepper);
      }
      pickCorrectFolder(row: any, stepper: MatStepper) {
        this.firstStep = true;
        this.cdRef.detectChanges(); // trigger the change detection manually to apply the completed state to the first step, which allows the stepper to move to the next step
        stepper.next();
      }
    

    My Stackblitz example

    Explained:

    When your button action is setting the completed value of your step and at the same time is handling the next action, the change detection is triggered once just after executing your logFolderRowData method. At the same time the next trigger directive matStepperNext will try to move to the next step, but at that moment the @Input() completed value is still false and the next action could not be taken until the completed is set to true. This is because the change detection was not triggered yet to apply the change of @Input completed on the Mat-Step. Triggering the change detection manually before calling the stepper.next() in the same method will apply the new value to the @Input completed on the Mat-Step and the action next will be successfully executed.