An Introduction to Angular CLI - Part 2 - Integrating Twitter Bootstrap

Twitter Bootstrap is one of the most popular and easy to use CSS frameworks currently available. It helps developers style their projects and make them presentable quickly and effortlessly.

We’re going to look at how easy it is to integrate Bootstrap into a very ugly looking to do list application built on top of Angular CLI and give it some character.

If you’re interested in finding out more about Angular CLI, check out my last post to learn it’s basic commands and how we built the list application.

Because our list application is scaffolded using the SASS style preprocessor, we’re going to be using the bootstrap-sass npm project, but it’s a similar process if your project uses plain CSS.

Let’s start by adding the package to our app using npm. In the terminal, type, npm i bootstrap-sass --save. The save flag adds the package to our package.json file.

$ npm i bootstrap-sass --save

Now let’s add a new SASS file called _variables.scss in the src directory. We’ll use this file to override any bootstrap variables so that we can customize our app and give it a unique look.

The first change we need to make to bootstrap’s default settings is the path to the fonts directory. Set the $icon-font-path variable to the path to our installed bootstrap package.

$icon-font-path: '../node_modules/bootstrap-sass/assets/fonts/bootstrap/';

Now we need to import bootstrap and our variables file into the project.
In our styles.scss file, add the following.

@import 'variables';
@import '../node_modules/bootstrap-sass/assets/stylesheets/_bootstrap';

The order of these imports is important. We import the variables file before bootstrap to make sure our overrides take priority.

If we’ve done everything properly, when we run our project using ng serve we should see our list’s font change from Times New Roman to Helvetica Neue.

Let’s update our item styles and give our list some life.

We’re going to use bootstrap’s list group to give each item it’s own container, and the grid system to center the list on the page. We’ll also give each item’s delete button a badge class to align it to the right.

<div class="row">  
  <div class="list-group col-sm-8 col-sm-offset-2">
    <button class="list-group-item" *ngFor="let item of list.items; let i = index">
      <button (click)="list.deleteItem(i)" class="badge">
        <i class="glyphicon glyphicon-remove"></i>
      <small>{{item.dueDate | date}}</small>

We’re getting there, but the button doesn’t look quite right so let’s add some styles to our component.

Any styles you apply to a component apply only to that component. This is known as view encapsulation. By default, angular enables this modularization to avoid class conflicts within your application, and group the components code together.

This means we can override our list items badge class without it affecting any other badges. Let’s give our badge a red background to make it look more like a delete button, and remove the border. We can find and import bootstrap’s variables file within the node_modules folder to make them available to us.

@import '../../styles';

.badge {
  background-color: $brand-danger;
  border: 0;

To demonstrate view encapsulation, let’s add another badge to our app component that shows the total number of items. In our app component class, lets expose the ListService class by first importing it, then injecting it into the constructor.

import { Component } from '@angular/core';

import { ListService } from './list.service'; // 1. import the ListService

  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
export class AppComponent {

  constructor(public list: ListService) {} // 2. inject the service into the controller


Now we can display the badge in the header.

<h1 class="text-center">  
  My Todo List 
  <span class="badge">{{list.items.length}}</span>


Finally, let’s add some functionality to let us mark an item as done. In the item interface, add an optional boolean flag called done. We’ll be able to toggle this flag by clicking on an item.

export interface Item {  
  title: string;
  dueDate: Date;
  done?: boolean; // add an optional "done" flag

Now in our list service we can add a toggle method to set the done flag.

toggleDone(index: number) {  
  this.items[index].done =! this.items[index].done;

Next in our list view file, we can add a click event that fires the toggle method when the user clicks an item and add an ngClass attribute to the list items that toggles the item’s active class if it’s marked as done.

<button class="list-group-item"  
  *ngFor="let item of list.items; let i = index"
  [ngClass]="{'active': item.done}" 
  <button (click)="list.deleteItem(i)" class="badge">
    <i class="glyphicon glyphicon-remove"></i>
  <small>{{item.dueDate | date}}</small>

[browser - http://localhost:4200]

Now our list is starting to take shape. There’s still some opportunities to enhance it’s functionality which we’ll cover in the coming posts.

comments powered by Disqus