Popups, Modals, and Navigation — Using Angular Material (2) Components in your Angular (2) Project

This article is part 3 of a 4 part series of using Angular Material (2) in your Angular (2) Angular-CLI project.

Part 1 Setting up your first Angular Project Using Angular Material (1/4)

Part 2 Using Angular Material2 Components in your Angular Project — Intro, Custom Styles, Buttons & Indicators (2/4)

Part 3 (this article) Using Angular Material Components in your Angular (2) Project — Popups, Modals, and Navigation (3/4)

Part 4 (coming soon) Using Angular Material (2) Components in your Angular (2) Project — Form Controls (4/4)

This article will show you how to use Angular Material components focused on popups, modals, and navigation.

Dialog Component

The dialog component by default is not styled, but the functionality and directives provided make it easy to create a skeleton dialog. All you have to do is add the styling.

The 4 directives available for dialog are:

md-dialog-title- the title of the dialog that you should add to a header tag.

<md-dialog-content>- the content of the dialog.

<md-dialog-actions>- a container for any action buttons of the dialog.

md-dialog-close- close attribute that should be attached to a close button on the dialog.

The docs are missing a few key steps for building this component, so I’ll walk you through how to build a simple test.

Creating a Dialog Component

First off, build the dialog component that you want to show up when you call it.

I created a component called dialog-example. All you have to do is run the command from the cli — ng g c -is -it --no-spec (that translates to ng generate component, add in-line styling, don’t add template and don’t add spec file).

Once you have the dialog-example.component.ts file generated, you can add in your template using the dialog directives.

<h1 md-dialog-title class="primary-color">hey title</h1>
<md-dialog-content class="accent-color">
hey this is the content of the dialog
</md-dialog-content>
<md-dialog-actions>
<button md-raised-button color="primary" md-dialog-close>
close button
</button>
</md-dialog-actions>

You’ll see above that I’ve done a few things. First, I’ve added custom styles to bring in the material design colors into my dialog’s html.

I’ve added md-dialog-title to the h1 tag.

I’ve put the content of my dialog into md-dialog-content.

I’ve added a close button in md-dialog-actions and md-dialog-close attribute to the actual button.

This is what the actual dialog component I created looks like.

Adding a button to open the dialog

You must add a button to open the dialog in your app. It’s a simple few lines of html. In this case, I’m creating the button in my main app component so I’m adding the code to app.component.html file. You can add it to any component you wish.

<div>
<button md-raised-button color="primary
(click)="openDialog()">Example Dialog - Click Me!</button>
</div>

Above, you’ll see I have simply created a material button using md-raised-button and added some color. More importantly, I’ve added a click event that calls a function, openDialog, which I’ll add to my TS file in just a moment.

The button should look like this.

Configuring your module file

In your app.module.ts file, though the cli will now include the component you’ve generated in your imports and add it into your declarations array for @NgModule, you’ll need to add a new array called entryComponents and include the DialogExampleComponent (or whichever component you are using to display the dialog) in there. If you don’t add it, your dialog just won’t pop up!

I’ve highlighted the entryComponents array below.

entryComponents: [
DialogExampleComponent
]

Configuring your component.ts file

I’m using the dialog in my main app component, so first, I’m going to import MdDialog into app.component.ts. Highlighted below. Though MdDialogis included in MaterialModule, for some reason the cli and my editor complain when I don’t import.

You’ll also see that I’m importing the dialog component I created so I can call it in the openDialog function I’m going to create.

Now, I’m going to add a constructor to my exports and a function that will open the Dialog Example component.

constructor(public dialog: MdDialog) {}
openDialog() {
this.dialog.open(DialogExampleComponent);
}

With all that and a bag of chips, you’re now ready to rock and roll and the dialog component should be working well.

Tooltip Component

The tooltip component allows you to create a little label that is displayed if you hover over a specified piece of text. I love this one because it requires no setup and just works.

mdTooltip in a span without mouse hover
mdTooltip in a span with hover and mdTooltipPosition right

It looks more beautiful in action, but it’s also great how light the code is for this functionality. Below.

<div>
<span mdTooltip="hey you" mdTooltipPosition="right">Hover over
for tooltip</span>
</div>

I chose my mdTooltipPosition to be right, but you can customize the position of the tooltip. There are 6 positions: above, below, left, right, before, and after.

You can add mdTooltip to almost anything, including buttons. Look how nice this looks.

And the corresponding code below.

<div>
<button md-raised-button color="primary" mdTooltip="hey look at
that" mdTooltipPosition="above">
This is a button with a tooltip
</button>
</div>

You are also able to customize when the tooltip is show with a delay input (mdTooltipShowDelay and mdTooltipHideDelay).

Snackbar Component

I love the little snackbar component because it’s slick and also pretty adorable.

Currently, the API for creating a snack bar that shows a component vs showing a string are a little different, so don’t be surprised to find little quirks while the Angular team works towards a release candidate.

Snackbar component displaying a string

First things first, you’ll want to add the snackbar service to something on your page. I’m going to add it to a button and am doing this in my main app component.

Below, you’ll see that all I’ve done is create a button in my html and say, when a click event happens, fire this function called openSnackBar.

<div>
<button md-raised-button color="primary"
(click)="openSnackBar()">Click to see snack bar</button>
</div>

This is what the button looks like.

Jumping into my app.component.ts file, we’ll have to do a few things.

For some reason, even though I imported MaterialModule, I still have to import MdSnackBar into my app.component.ts file.

import { MdSnackBar } from '@angular/material';

After that, I’ll have to export a public constructor. I’m calling it snackBar and telling TypeScript that it is of type MdSnackBar.

constructor(public snackBar: MdSnackBar) {}

With snackbar, you have a few options when you display a string. You can add an action which creates a button (maybe a cancel or close button) and the duration of how long you’d like to keep the snackbar showing, if any.

You can decide if you want to use the action or duration features of the snackbar component.

If you recall the function I was trying to call in my html, it was called openSnackBar.

openSnackBar() {
this.snackBar.open("hey now", "close", {
duration: 2000,
});
}

Then, when I click on the button in my html, a little snackbar should pop up to say hello! I can click the close button if I want to close the snackbar immediately, or, because I’ve added a duration, the snackbar will automatically close in 2000ms.

Snackbar component displaying a component

Displaying another component inside the snackbar gets fun because you can add emojis and pictures and other fun things and obviously customize your little snack a bit more.

The first thing I’ll want to do is create the component I’m displaying. Do that by running in terminal ng g c -is -it --no-spec (ng generate component with in-line styles, in-line template, and no test file).

Add something to the component html. In my case, I added some emojis.

Configure your app.module.ts file by making sure you’ve specified that this component you just created is an entry component in @NgModule.

entryComponents: [
SnackComponentComponent
]

Then, in your app.component.ts file, it’s time to get your snackbar working!

I find it strange you have to import your component in to the file you’re adding your function, but whatever. Do that first.

import { SnackComponentComponent} from './snack-component/snack-component.component';

Create a public constructor like you did for the last snackbar. Call it something different if you’re using two snackbars.

public snackBarComponent: MdSnackBar

How you call the snackbar to open is a little different here. Instead of .open, you use .openFromComponent. You cannot add an action when calling snackbar to open a component, but you can add the duration still.

openSnackBarComponent() {
this.snackBarComponent.openFromComponent( SnackComponentComponent, {
duration: 2000,
});
}

You’ll see that my button looks the same…

But I can make my snackbar so much cooler.

Navigation

The navigation components in Angular Material2 currently consist of 3 components to choose from: Toolbar, Sidenav, and Menu.

Toolbar Component

The toolbar component is probably one of the most important components of Angular Material2 and helps you make beautiful header and footers!

You can also use the toolbar container as a component for headers and actions.

The toolbar component can be multiple rows and styled with the three main colors of your app — primary, accent, and warn. The multiple row function works great for side navigation.

If you are using the toolbar component as a navigation bar or footer, you’re going to want to add some custom css to make the toolbar fit the width of the screen.

Quite honestly, I’ve solved this problem a lot of ways, but tonight I can’t figure out a better way to solve it than put margin: 0px on body and then wrapping the rest of html in a div with 50px margins.

You can play with the best way you want to do this, but for my solution, add this little bit of css to your styles.css file.

body {
margin: 0px;
}
.margin-left-right-50 {
margin-left: 50px;
margin-right: 50px;
}

Simple navbar code below.

<md-toolbar color="primary">My App</md-toolbar>

This is what the navbar looks like without the css.

And with the css.

Stacked Toolbar

The stacked toolbar consists of creating rows using md-toolbar-row after the first row which need not be in md-toolbar-row.

<div>
<md-toolbar>
<span>First Row</span>
<md-toolbar-row>
<span>Second Row</span>
</md-toolbar-row>
<md-toolbar-row>
<span>Third Row</span>
</md-toolbar-row>
</md-toolbar>
</div>

Simply, it ends up looking like this.

But, what’s more beautiful is when you take that stacked toolbar and use it in a side nav. Let’s review the side nav component to see how that looks.

Sidenav Component

For the sidenav, the first thing you should realize is that everything needs to be wrapped in a sidenav container. It’s also nice to keep the sidenav fullscreen — it just looks better.

<md-sidenav-container fullscreen></md-sidenav-container>

Then, create your actual sidenav. This should go at the very top of your page. This is the perfect opportunity to use the stacked toolbar version of md-toolbar.

<md-sidenav #sidenav mode="side">
<md-toolbar>
<span>First Row</span>
      <md-toolbar-row>
<span>Second Row</span>
</md-toolbar-row>
      <md-toolbar-row>
<span>Third Row</span>
</md-toolbar-row>
</md-toolbar>
</md-sidenav>

In order for your sidenav to work, you need to give your sidenav a local variable. I gave mine #sidenav to keep it simple. I chose the mode “side” because I like that it pushes the content over to the side.

Over, push and side, are the three modes available for md-sidenav. Over will float over the main content, whereas push will push over the main content. Side shows the content and sidenav side by side.

You’ll need to add a button that actually opens the sidenav. You can do that in your main navbar! Below you’ll see that I am allowing the button to toggle, but you can also choose open as the method.

I added an md-icon to make the button a nice hamburger.

<button md-button (click)="sidenav.toggle()">
<md-icon>menu</md-icon>
</button>

This is what the button looks like.

And when you click the hamburger, the sidenav appears and spans the entire page.

Here’s the full code for this page so you can get a better idea of what’s going on.

<md-sidenav-container fullscreen>
<md-sidenav #sidenav mode="side">
<md-toolbar>
<span>First Row</span>
<md-toolbar-row>
<span>Second Row</span>
</md-toolbar-row>
<md-toolbar-row>
<span>Third Row</span>
</md-toolbar-row>
</md-toolbar>
</md-sidenav>
<md-toolbar color="primary">
<button md-button (click)="sidenav.toggle()">
<md-icon>menu</md-icon>
</button>
<span>My App</span>
</md-toolbar>
<div class="margin-left-right-50">
<div>
<h3 class="primary-color">
Snackbar displaying string
</h3>
</div>
<div>
<button md-raised-button color="primary" (click)="openSnackBar()">Click to see snack bar</button>
</div>
<div>
<h3 class="primary-color">
Snackbar displaying component
</h3>
</div>
<div>
<button md-raised-button color="primary" (click)="openSnackBarComponent()">Click to see snack bar</button>
</div>
<h3 class="primary-color">
Stacked Toolbar
</h3>
<div>
<md-toolbar>
<span>First Row</span>
<md-toolbar-row>
<span>Second Row</span>
</md-toolbar-row>
<md-toolbar-row>
<span>Third Row</span>
</md-toolbar-row>
</md-toolbar>
</div>
</div>
</md-sidenav-container>

Also, you can specify the width of the sidenav if you like! Just use ` width: 200px; or whatever your width desires in your styles.css or component css file.

Menu Component

The menu component is so easy, you can literally copy/paste the code and it works.

First, what we need is a button on the page that triggers the menu to open.

Below I am using the md-icon button component and adding in a directive and specifying a local template variable. [mdMenuTriggerFor]="menu". The variable specified, menu, I will add to my actual menu component soon.

<button md-icon-button [mdMenuTriggerFor]="menu">
<md-icon>menu</md-icon>
</button>

You’ll see below what the button looks like as I hover over it.

The actual menu information can go right below the button information. In md-menu, create the local template variable (the same one you named on your button to open the menu) and specify that it is a mdMenu.

In the menu, a each row is considered an md-menu-item and should be a button. This button can have a route added to it or a function — whatever you need for your app. I am using the md-icon component below to have a nice icon within each button.

You’ll see on the second button I can specify the attribute disabled if I want that button to be disabled.

<md-menu #menu="mdMenu">
<button md-menu-item>
<md-icon>dialpad</md-icon>
<span>Call 1-800-SOO-COOL</span>
</button>
<button md-menu-item disabled>
<md-icon>voicemail</md-icon>
<span>You can't check your voicemail</span>
</button>
<button md-menu-item>
<md-icon>notifications_off</md-icon>
<span>Do Not Disturb</span>
</button>
</md-menu>

This is what the menu looks like. I am hovering over the first md-menu-item.

Pretty cool right?

We have now gone over popups, modals, and navigation components in Angular Material!

Part 4 in this series is coming soon and will cover form controls.

PS you can find me on twitter @ladyleet or at a local conference! Find my schedule at ladyleet.com.