Steppers are used to guide users through a sequential series of steps in order to complete a task like registration. Steps are typically numbered and content is broken into logical units. Don’t nest steppers, as in a stepper within a stepper.
This will confuse your users. You can allow your users to go back and change their selection or you can force them to start over. A linear stepper requires the steps be completed in a specific order. While a nonlinear stepper allows a user to bounce back and forth between steps. Also, some steps can be marked as optional.
Horizontal steppers are typical in desktop while mobile tends to use vertical steppers since there’s less real estate on the device. Let’s add a stepper to our application in the messages module. We’ll create a stepper that requires that the user enter an email address in step one and then the body of their message is step two.
We’ll experiment with linear and nonlinear and see how the performance changes. The first thing I’m going to do though is I’m going to create a new component ng generate component messages/message-new. This is going to be what we’re going to use to create our stepper.
From here, I’m going to go to the messages.module from command p and we have a bunch of things that we’re going to want to import here. So from the top, I’m going to have to add the forms module now. Because we’re going to be creating a form within our message stepper. So I’m going to import the Forms Module as well as the Reactive Forms Module on line three. From Angular forms and then moving down a little bit I’m going to go add some material stuff. So on line nine, I’m going to add a comment here for Material.
And I’m going to import the MatButtonModule from @angular/material/button. I’ll copy that three more times. And on line 11 we’re going to change this next one to the MatFormFieldModule and that comes from Material/form-field. On line 12, we’re going to change this one to MatInputModule, ’cause we’re going to have some inputs in our stepper and that comes from the input. And lastly on line 13 we’re going to go ahead and change the MatStepperModule here and this comes from the stepper.
Moving down, I’m going to go ahead and add a comma on line 18 and we’re going to add the FormsModule that we imported earlier as well as the ReactiveFormsModule and I’m going to go down after that comma put another note for Material here and let’s put our MatButtonModule our MatFormFieldModule, our MatInputModule and our MatStepperModule here as well. And now we have everything ready to update the UI.
Next, let’s add the routing instructions for our new component, I’ll command p and we’re going to go to the message routing module. And we’re going to need to import our new component that we created here, this is one thing we don’t get for free from the generate component. Import the MessageNewComponent from .message-new/message-new.component. And we’re going to copy this path from line seven to 10 I’ll put a comma on line 10, paste that and we’ll say that the path new now goes to the MessageNewComponent.
Third module’s imported, I can now command p and go to the message-new.component.html and you see I’ve got the text here that says message-new works, let’s go ahead and clear that out and we’re going to add the new mat-horizontal-stepper element here. And I’m going to say linear in a square bracket equals true for now and I’m going to use the id stepper on this component. But then here we’re going to add mat-steps so I’m going to add three steps. And then we’re going to put a control on that step so stepControl square bracket equals firstFormGroup and we’re going to add these to our component definition in a little bit and the next one we’re going to go ahead and say that the stepControl square brackets again equals secondFormGroup and we won’t put a control on our third one ’cause our third one was not going to do a whole lot.
But I do want to demonstrate one thing which is optional equals true, so we’ll put that optional flag on there just to see what that component actually does. Next, let’s go ahead and open up our mat-step on line two, our first one in here. And let’s put a form in here and I’m going to use the formGroup directive equals firstFormGroup. And I’m going to put an ng-template in here for the header and this is a matStepLabel and I’m going to say enter recipient info. And I’m going to go ahead and add a mat-form-field below this on line five, mat-form-field and we’ll put an input in here remember we imported the input module for Material so we’ll get good-looking imports placeholder equals email, formControlName equals emailCtrl and we’ll make it required just so we get the prettiness on there with the red stars and everything.
Okay, now let’s go to line 10 our second step. And we’re going to go ahead and put a form in here as well and this formGroup directive is going to point to secondFormGroup, same as above. Inside that form I want to put another form-field here as well and this is going to use the matInput directive as well with a placeholder this time called message, and our formControlName here is going to be messageCtrl and we’ll make this one required as well ’cause you can’t have an email without a message.
Next, we’re going to add some buttons here to move around, just to make it easy for our users. I’m going to go ahead and create a div for those buttons and we’ll create a button using the mat-icon-button directive and the matStepperPrevious which tells the stepper to move to the previous step since we know this is step two. And I’m going to put a mat-icon in here because I like icons more than words and we’ll use the arrow_back icon in here. Now I can copy this, I want to make another button this time to go forward and in here I’m going to go ahead and use the matStepperNext and I’m going to go ahead and change this icon instead of using arrow_back I’m going to use the send mail, so we’ll just use a mail_outline so it looks like a piece of mail.
And now that I’ve done that I’m going to copy this and let’s add a next step too on the one above. So back on line seven let’s put a div sibling to this and we’ll put a arrow in here that’s a stepperNext and that’s going to say arrow_forward. And I’m going to go ahead and format this command p, greater than format document. Want this to start cleaning up a little bit. And lastly let’s go down to the bottom mat-step optional equals true and I want to go ahead and put something in here as well so I’m just going to go ahead and put a message to the user so I’m going to add an ng-template matStepLabel we’ll call this one preview and I’ll put a p in here that says message sent.
And we’ll give them a couple more options here I’ll put a div in here and I’m going to copy from line 24 to 26, I just want to grab these two buttons I’m going to put two buttons in here as well. And I’m going to put one that says arrow_back. On line 35 and we’ll use the stepPrevious. And this last one here we’re going to make a reset so I’m going to go ahead and change this one instead of using matStepperNext I’m going to say on click, stepper.reset. And instead of using the mail icon here let’s go ahead and use the refresh which looks like a reset, at least it will for our purposes here.