javascripthtmlangularmat-stepper

mat-vertical-stepper set page to the start of the stepper when next is clicked


I have a very long form, and I am trying to make it more usable for the user. I found this code as a reduced example of the code I work on https://stackblitz.com/edit/angular-yz6dqk-c9zouk?file=app%2Fstepper-overview-example.html.

What i want to accomplish here is to focus in the beginning of the next step (or title). When the first part of the form is long enough to have to scroll down to reach the next button and you press it, the html scroll position is kept and the second part of the form is loaded, meaning that this second part of the form does not show from the start (or title), it shows the questions that are at the position where the next button was, and the user has to scroll up to get to the first question.

What i want to accomplish here is to avoid the user scrolling up to search for the first question, automatically scroll up the page to the point where the title is set.

I'll try to explain with an example: here is an image of the start of the form when is new: enter image description here, to reach the next part of the form you have to scroll down and reach the end of the page to find the next button: enter image description here. Once you click next the second part of the form loads: enter image description here, but... hey!... do you see where the web page scroll is?, is in the middle, almost the end, is not showing the first question of the second part but rather the ending of the form, i have to scroll up manually to go to the top and search the first question: enter image description here, see where the scroll is now? i want to go there automatically (where the second form starts) when the next button is press instead of starting at the buttom.


Solution

  • after looking a lot creating a directive solved my problem.

    import { Directive, HostListener } from '@angular/core';
    import { MatStepper } from '@angular/material/stepper';
    
    @Directive({
      selector: 'mat-vertical-stepper',
    })
    export class MatVerticalStepperScrollerDirective {
      constructor(private stepper: MatStepper) {}
    
      @HostListener('animationDone')
      selectionChanged() {
        const stepId = this.stepper._getStepLabelId(this.stepper.selectedIndex);
        const stepElement = document.getElementById(stepId);
        if (stepElement) {
          stepElement.scrollIntoView({ block: 'start', inline: 'nearest', behavior: 'smooth' });
        }
      }
    }