angulartypescriptangular-material-stepper

Angular Material Stepper 'Paginate'


I have many steps in my stepper, so i want to divide it in two parts, i.e.

When users goes inside wizard, the stepper header shows only 1--2--3--4, then, when step 4 is finished, and the user goes into step 5, the header shows 5--6--7--8, and so on for next steps.

Do you know any way to do this?

Thanks in advance.

Edit:

I tried using *ngIf to hide/unhide steps, but it does remove those steps from the stepper array, so entered information losts when step hides.

Here is my *ngIf approach: https://stackblitz.com/edit/angular-material2-beta-kknvx9

Also, tried a similar approach with [hidden], but it does not work at all.


Solution

  • The problem is that the mat-step changes to mat-step-header when it renders and any custom class or attribute on it will be gone.

    The following code works but it's messy. The best solution is to find another wizard component that has what you need or to submit a request for Material developers on GitHub to add a hidden flag to the mat-step.

    StackBlitz

    Class:

    export class AppComponent implements OnInit, AfterViewInit{
      private ngVersion: string = VERSION.full;
    
      MAX_STEP = 7;
    
      @ViewChild('stepper') private myStepper: MatStepper;
      step: number = 0;
      page:number = 0;
    
      constructor() {}
    
      ngOnInit() {}
    
      ngAfterViewInit() {
        this.rerender();
      }
    
      goBack() {
        if (this.step > 0) {
          this.step--;
          this.myStepper.previous();
        }
        this.page = this.step > 3 ? 1 : 0;
        this.rerender();
      }
    
      goForward() {
        if(this.step < this.MAX_STEP) {
          this.step++;
          this.myStepper.next();
        }
        this.page = this.step > 3 ? 1 : 0;
        this.rerender() 
      }
    
      private rerender() {
    
        let headers = document.getElementsByTagName('mat-step-header');
        let lines = document.getElementsByClassName('mat-stepper-horizontal-line');
    
        for (let h of headers) {
          if (this.page === 0) {
            if (Number.parseInt(h.getAttribute('ng-reflect-index')) > 3) {
              h.style.display = 'none';
            }
            else {
              h.style.display = 'flex';
            }
          }
          else if (this.page === 1) {
            if (Number.parseInt(h.getAttribute('ng-reflect-index')) < 4) {
              h.style.display = 'none';
            }
            else {
              h.style.display = 'flex';
            }
          }
        }
    
        for (let i = 0; i < lines.length; i++) {
          if (this.page === 0) {
            if (i > 2) {
              lines[i].style.display = 'none';
            }
            else {
              lines[i].style.display = 'block';
            }
          }
          else if (this.page === 1) {
            if (i < 4) {
              lines[i].style.display = 'none';
            }
            else {
              lines[i].style.display = 'block';
            }
          }
        }
    
      }
    
    }
    

    View:

    <div class="solution">
    
      <!--------------------------------------------------------------------------------------->
      <mat-horizontal-stepper #stepper>
        <mat-step>
          Step 1
        </mat-step>
        <mat-step>
          Step 2
          <input matInput placeholder="Address" required>
        </mat-step>
        <mat-step>
          Step 3
        </mat-step>
        <mat-step>
          Step 4
        </mat-step>
        <mat-step>
          Step 5
        </mat-step>
        <mat-step>
          Step 6
          <input matInput placeholder="Address" required>
        </mat-step>
        <mat-step>
          Step 7
        </mat-step>
        <mat-step>
          Step 8
        </mat-step>
        <!-- one option -->
      </mat-horizontal-stepper>
    
      <!-- second option -->
      <div>
        <button (click)="goBack()" type="button" [hidden]="step === 0">Back</button>
        <button (click)="goForward()" type="button" [hidden]="step === MAX_STEP">Next</button>
      </div>
      <!--------------------------------------------------------------------------------------->
      Step: {{step}}
      <br>
      Page: {{page}}
    
    </div>