3

I’m working in an Angular application. I have a MatHorizontalStepper and I’m wondering how to prevent the default behaviour of the next and back buttons. I thought I could just use event.preventDefault() in the click handlers but that doesn’t seem to work.

Here’s the HTML for the buttons:

<mat-horizontal-stepper>
…
  <button *ngIf="scrnIndex > 0" mat-raised-button matStepperPrevious type="button" (click)="backClicked($event, scrnIndex)">Back</button>
  <button *ngIf="scrnIndex < formScreens.length - 1" mat-raised-button matStepperNext type="button" (click)="nextClicked($event, scrnIndex)”>Next</button>
…
</mat-horizontal-stepper>

Here’s the click handler:

nextClicked(event, screenIndex) {
  event.preventDefault();
  this.validateCurrentPage(screenIndex);
}

What I’m trying to do is prevent the stepper from going to the next page until the user clicks “confirm” on a dialog that comes up in response to any invalid values on the page (this means that we don’t necessarily want to stop the user from going forward with invalid values, but we do want to warn them with a dialog).

The function ValidateCurrentPage() does the check and brings up a dialog if it detects any invalid values:

ValidateCurrentPage() {
    …
  const dialog = new GeneralDialogModel(
    'Past Dates/Times Detected',  // Title
    'One or more dates and/or times are in the past. Is this intentional?', // Content text
    'Yes',                        // Confirm button text
    'No');                        // Cancel button text
  const dialogRef = this._dialog.open(GeneralDialogComponent, { data: dialog });
  dialogRef.afterClosed().subscribe(result => {
…
  });
…
}

Because the dialog runs on a different thread, validateCurrentPage() returns before the user can click “yes” or “no”, which means the click event handler returns before the user can click “yes” or “no”. Then the default behaviour of the click event occurs: the stepper goes to the next page. event.peventDefault() didn’t stop it.

What I’d like to do is stop the default behaviour and then programmatically go to the next page when the user clicks “yes”. But I need to know how to stop the default behaviour (or pause it until I programmatically unpause it) in order to do that.

Gibran Shah
  • 871
  • 3
  • 15
  • 34
  • this example could give you an idea, I mean it is not the final solution but it gives you some way to control the stepper https://stackblitz.com/edit/angular-material2-issue-9lskal – Daniel C. Oct 26 '18 at 19:51

1 Answers1

0

One solution:

  1. remove the matStepperNext directive on that button
  2. gain access to the stepper in the component typescript file using @ViewChild(MatStepper, {static:true}) and store that in a member variable (say, "stepper") - note, the static field is required in later angular versions.
  3. in ValidateCurrentPage(), call this.stepper.next() to trigger the stepper to the next step.

Hope that helps! More steppe info here: https://material.angular.io/components/stepper/api

RocketMan
  • 441
  • 4
  • 15