Angular Material Stepper With Pagination

Madhura Gore
6 min readMar 31, 2021

--

Angular Material’s stepper provides a wizard-like workflow by dividing content into logical steps. This type of workflow design pattern is commonly used in UI when we have long forms which can be broken down into groups of similar form fields or when there’s an activity having sequential flow of logic. For example, on an E-commerce website, you might encounter a step by step process of placing your order at the time of checkout, where step 1 asks for your name and address, step 2 contains review of cart items and step 3 asks for the payment details.

For a quick overview of Angular Material Stepper, you can check this link:

TL;DR? Check out the working demo over here:

https://angular-mat-stepper-paginator.stackblitz.io

The problem: While working on a similar use case where we had a long form of around 8–10 steps, we wanted to use the horizontal stepper along with a paginator. But with the horizontal stepper, the step titles would become congested when showing all of them together in the view at the same time. (And of course, you wouldn’t want to include that nasty horizontal scrollbar on your page!) Something like this:

For this reason, we needed something like a paginator which can move back and forth between the steps and the stepper would look more appealing. Currently, there is no support from Angular Material with such kind of customization and there are several requests to include this functionality.

There’s an option of using vertical orientation of the stepper, but here’s how it looks like when there are large number of steps:

As you can see, there’s much of a blank space on the page when the steps are in collapsed form and we didn’t find this appealing for our purpose.

The solution: So, coming back to our horizontal stepper, we did work on a solution and were able to overcome the problem! Phew!

There isn’t any direct approach to show / hide steps in the mat-stepper. That’s why when we try applying ngIf / hidden to mat-step, it removes the step from the view. For example, if you have 8 steps and try to hide the first 2 steps using ngIf, it takes as if there are a total 6 steps and re-assigns the step indexes of each step. (Index of step 3 becomes 1, that of step 4 becomes 2 and so on up to step 6). To fix this behaviour, the steps which should not be visible in the view need to have a display as “none” and this can be achieved by manipulating the DOM through template reference along with pagination logic.

We’ll talk about different approaches we can have for navigation and pagination in the stepper. The main logic revolves around 2 variables — min and max steps we want to display in the view at any given point.

Solution 1:

Consider you have a total of 8 steps and the maximum number of steps that you want to show on the page at any time is 4. You want your back and next buttons to navigate through each step of the stepper.

This will simply bring 4 steps into view at any given time. At the start, you’ll have steps 1–4 into view. To go from step 1 to 4, you’ll click on next arrow button 3 times and if you click on next button after reaching step 4, the steps 2–5 will come into view as below:

So at any given time, you have a frame of 4 steps which you’re moving from step to step. For example, 1–4, 2–5, 3–6, 4–7 or 5–8. This solution would only act as a navigator from step to step and we aren’t doing any pagination work over here.

Solution 2:

In this type, we have the arrow buttons acting as a navigator as well as a paginator. Also, the frame of 4 steps will now look something like:

The frames over here act like pages. You’ll have pages of steps 1–4 and steps 5–8 (9–12 and so on if you have more steps). The obvious question over here would be what if we want a frame of 3 steps? In this case, our maximum steps in view would remain 3 and to maintain evenness, we’ll have page frames like:

For the last frame, as can be seen above, the frame size still remains 3 and without disturbing the consistency of user view, we can show the steps into view.

Continuing with our 4 steps example,

At the start, To go from step 1 to 4, you’ll click on next arrow button 3 times and when you click on next arrow button after step 4, you’ll not only have a new single step, but the page frame would get changed to steps 5–7:

At any given time, we’ll have either steps 1–4 or steps 5–7 into view in this approach.

Solution 3:

The page frames from solution 2 remain the same in this approach, i.e. we’ll have steps 1–4 or 5–7 into view at any given point. But in solution 2, if you want to navigate from step 1 to step 5, you’ll first need to navigate through steps 1, 2, 3, 4 and then only step 5 would be visible. Solution 3 would help you directly navigate from step 1 to step 5, i.e. you can change the page without going through individual steps in between. For that, we’ll separate the navigation and pagination into 2 parts — the 2 arrows (forward and backward) will act as paginators and the 2 action buttons (Back and Save and Continue) will act as navigators. This would be better from the usability perspective where you’re saving the user actions if the user wants to check what’s there in the next steps in the form.

Rendering Logic:

Depending on your page frame and the min and max step indexes you want to show in the view, you’ll just display the steps which fit into the min — max step range and for other steps, as mentioned above, we’ll set the display to “none”. Same goes for the horizontal lines joining the steps.

So, the above summary was the logic behind the stepper with paginator that we’ve implemented. You can refer to the Angular code over here:

Happy Coding!

--

--

Responses (1)