The simple way to make a mobile Angular 2 Bootstrap navbar without jQuery
There aren’t any major UI template libraries ready for plug and play in Angular 2 yet. Angular 2 Material Design is in alpha. The Bootstrap library for Angular 2 is also in development on Github, but not ready for prime time. This means that we’re left largely to our own devices to build the UI for our Angular 2 projects.
Let’s take a look at how we can get our Angular 2 project going using Bootstrap, but only the stylesheets — no bootstrap.js or jQuery. We’ll use Bootstrap 3, the current stable release, rather than Bootstrap 4 that the
Angular 2 Bootstrap project is targeting.
In this article, we’ll build a Bootstrap navbar as an Angular 2 component and enable its mobile view toggle functionality through the component class.
We’ll take the path of least resistance and simply get the menu to show and hide. For this tutorial, we’ll forgo the transition animation.
To get started, create the NavbarComponent. I put mine in the CoreModule of my Angular 2 application. To learn more about the module architecture I use, read this article.
We start with a bare bones Bootstrap navbar. The .collapse css classes are not added to the html yet.
<!-- core/navbar.component.html -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand">Project Manager</a>
</div>
<ul class="nav navbar-nav">
<li><a>Link 1</a></li>
<li><a>Link 2</a></li>
</ul>
</div>
</nav>
The TypeScript file contains the following.
// core/navbar.component.ts
import { Component } from '@angular/core';@Component({
selector: 'ct-navbar',
templateUrl: 'app/core/navbar.component.html'
})
export class NavbarComponent { }
Add the navbar to the in the AppComponent template.
<!-- /app.component.html -->
<!-- navbar -->
<ct-navbar></ct-navbar>
<!-- feature content -->
<ct-project-center></ct-project-center>
Run the app and the navbar will render as follows.
Notice that bootstrap.css handles the display of the mobile navbar for us with a media query — @media(min-width: 768px){...}
To get our navbar to collapse, we add some more markup to our template, using the Bootstrap documentation as our guide.
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button> <!-- #1 -->
<a class="navbar-brand">Project Manager</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a>Link 1</a></li>
<li><a>Link 2</a></li>
</ul>
</div> <!-- #2 -->
</div>
</nav>
- Add the <button> with the navbar-toggle and collapsed classes. It is shown when the browser viewport width is less than 768px.
- Wrap the <ul> element in a <div> with the collapse and navbar-collapse classes. This will cause the controls in the <ul> list to no longer be displayed on the mobile view.
Try adding the in class to the <div>.
<div class="collapse navbar-collapse in">
You’ll see that adding this class is the mechanism for expanding the menu.
To get the menu to work, we need Angular to toggle this class for us.
NgClass
Angular provides the NgClass directive as a means to add and remove classes from html elements. It accepts three different types of input as an argument:
- string — Input a string to ngClass to add one or more classes. Multiple classes are separated by a space. e.g.
[ngClass]="'first second'"
- Array — Input an array containing the string values of the classes you want to add.
- Object — Input an object where the object property represents the class. The property is set to a boolean indicating whether or not the class should be added to the the html element.
NgClass is part of the CommonModule, which most likely has already been imported into the module you are working on.
We’ll apply the NgClass directive to our template, inputting an object as an argument.
<!-- core/navbar.component.html -->
...
<div class="collapse navbar-collapse"
[ngClass]="{ 'in': true }">
<ul class="nav navbar-nav">
<li><a>Link 1</a></li>
<li><a>Link 2</a></li>
</ul>
</div>
...
We hard coded in the value true just to get a handle on the syntax and verify it works. Run the app and verify that the navbar is open at the mobile
screen size.
In the component class, let’s create a variable to store the state of the navbar and create a method to use as the click handler.
// core/navbar.component.ts
...
export class NavbarComponent {
isIn = false; // store state
toggleState() { // click handler
let bool = this.isIn;
this.isIn = bool === false ? true : false;
}
}
Now we make use of these component properties in our template.
<!-- core/navbar.component.html -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button"
class="navbar-toggle collapsed"
(click)="toggleState()">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand">Project Manager</a>
</div>
<div class="collapse navbar-collapse"
[ngClass]="{ 'in': isIn }">
<ul class="nav navbar-nav">
<li><a>Link 1</a></li>
<li><a>Link 2</a></li>
</ul>
</div>
</div>
</nav>
That’s it. We now have a functional navbar.
This same method can be applied to make use of many Bootstrap components in your Angular 2 project, including drop-down menus and accordion-style collapsible panels.