Web Programming TutorialsLearn How to Build a Tabs Component APP in Angular 2

Learn How to Build a Tabs Component APP in Angular 2

tabs-component

In this chapter, we are going to build a Tabs component app in Angular 2.0. In this app, we will code in TypeScript and ES5 in order to demonstrate the use of dependency injection to get parent component details. On the web page, we can click on the tabs hyperlink to gather the Tab text detail and display the same text on the screen.

In Angular 1.x, we can build such an app by using directive controllers. But in Angular 2.0, the concept of directive controllers is obsolete and replaced by the Component using the help of dependency injection. In Angular 2.0, the component user resolves on how the values are passed to the Component. On the other hand, in Angular 1.x, the directive describes how a value is bound to its scope, therefore the consumer requires to know about the inner workings of a directive.

Angular 2.0 coding for Tabs Component
app/main.ts

import { platformBrowserDynamic }    from '@angular/platform-browser-dynamic';
import { AppModule } from './app-module';
platformBrowserDynamic().bootstrapModule(AppModule);

Explanation of Code:
The above main.ts file is used to Bootstrap the angular 2.0 app that uses the root component from the NgModule.

app/app-module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app-component';
import { TabsComponent } from './my-tabs-component';
import { TabComponent } from './my-tab-component';

@NgModule({
  imports: [BrowserModule],
  declarations: [AppComponent, TabComponent, TabsComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}

Explanation of Code:
The root App Module typescript file is present in the app package. Here, we are importing the NgModule, BrowserModule, TabsComponent, TabComponent, and AppComponent classes as shown above. The @NgModule decorator is declared here that has imports, declaration classes and bootstrap class to start the app.

app/app-component.ts

import { Component } from '@angular/core';
import { Tab } from './my-tab-interface';
import { TabComponent } from './my-tab-component';
import { TabsComponent } from './my-tabs-component';

@Component({
  selector: 'my-tab-app',
  templateUrl: 'resource/app-component.html'
})
export class AppComponent {
  
  details:string[] = [];
  
  heading = "Tab Component example in Angular 2.0";
  paragraph1 = "The Tabs component are written in ES5, to demonstrate the use of dependency injection to get parent component details.";
  paragraph2 = "Click on the Tabs links to gather the Tab text.";
  
  detail(selectedTab:Tab) {
    this.details.push('Selected Tab with title: ' + selectedTab.tabText);
  }
}

Explanation of Code:
Here, we are declaring the component with selector as ‘my-tab-app’ and templateUrl as ‘resource/app-component.html’ that has the required HTML code to render on the web page. The controller class ‘AppComponent’ has an array of string type (details: string []) that holds the selected text from the tabs. Next, we are writing a function i.e. detail (selectedTab: Tab) that has event binding with the ‘selected’ event that will eventually call this function to display the selected text on the screen when the tab is selected.

resource/app-component.html

<h2>{{heading}}</h2>
<p>{{paragraph1}}</p>
<p>{{paragraph2}}</p>
<hr>
<br>
<my-tabs-comp (selected)="detail($event.selectedTab)">
  <my-tab-comp [tabText]="'Tab Component Title 1'">
    You have selected Title 1
  </my-tab-comp>
  <my-tab-comp tabText="Tab Component Title 2">
    You have selected Title  2
  </my-tab-comp>
  <my-tab-comp [tabText]="'Tab Component Title 3'">
    You have selected Title  3
  </my-tab-comp>
  <my-tab-comp [tabText]="'Tab Component Title 4'">
    You have selected Title  4
  </my-tab-comp>
</my-tabs-comp>

<h3>You Selection Tab Text is:</h3>
<ul>
  <li *ngFor="let detail of details">
    {{detail}}
  </li>
</ul>
<hr>

Explanation of Code:
Here, we are declaring the nested tags as ‘my-tabs-comp’ and ‘my-tab-comp’. The ‘my-tab-comp’ tag has the property binding with ‘tabText’ which is declared as string type in the interface ‘Tab’ as shown below. This is to be noted that the property binding for [tabText]=”‘Tab Component Title 1′” and tabText=”Tab Component Title 2″ serves the same purpose in Angular 2.0. Later in the HTML code, we are displaying the list of selected Tab text on the screen by using the *ngFor directive to iterate over the ‘details’ list.

app/my-tab-interface.ts

export interface Tab {
  tabText: string;
}

Explanation of Code:
It is an interface that has a variable ‘tabText’ declared as that of the string type.

app/my-tab-component.ts

import { Component, Input, OnInit } from '@angular/core';
import { Tab } from './my-tab-interface';
import { TabsComponent } from './my-tabs-component';

@Component({
  selector: 'my-tab-comp',
  templateUrl: 'resource/my-tab-component.html'
})
export class TabComponent implements OnInit, Tab {
  
  @Input() tabText;
  
  constructor(private tabsComponent: TabsComponent) {}
  
  ngOnInit() {
    this.tabsComponent.addTab(this);
  }
}

Explanation of Code:
In the ‘app-component.html’ file we have used the tags ‘my-tab-comp’ which is nothing but the component selector that has underlying HTML defined in the template file ‘resource/my-tab-component.html’ as shown below. It has the controller class ‘TabComponent’ that implements ‘OnInit’ and ‘Tab’ interfaces. In the class, ‘tabText’ is overridden or implemented as the Input by using @Input class field decorator and we are adding the tab by calling the ‘addTab’ function of TabsComponent controller class (explained next) inside the ‘ngOnInit’ component change directive.

resource/my-tab-component.html

<div [hidden]="!selected">
  <ng-content></ng-content>
</div>

Explanation of Code:
It is the HTML template for ‘my-tab-component’, it has the expression ‘! selected’ that has the property with HTML ‘hidden’ event. Therefore, when the value of this expression is true, the contents will be displayed and when false the contents will be hidden.

app/my-tabs-component.ts

import { Component, EventEmitter, Output } from '@angular/core';
import { Tab } from './my-tab-interface';

@Component({
  selector: 'my-tabs-comp',
  templateUrl: 'resource/my-tabs-component.html'
})
export class TabsComponent {
  
  tabs:Tab[] = [];
  @Output() selected = new EventEmitter();
  
  addTab(tab:Tab) {
    if (!this.tabs.length) {
      tab.selected = true;
    }
    this.tabs.push(tab);
  }
  
  selectTab(tab:Tab) {
    this.tabs.map((tab) => {
      tab.selected = false;
    })
    tab.selected = true;
    this.selected.emit({selectedTab: tab});    
  }
}

Explanation of Code:
In the ‘app-component.html’ file we have used the tags ‘my-tabs-comp’ which is nothing but the component selector that has underlying HTML defined in the template file ‘resource/my-tabs-component.html’ as shown below. It has the controller class ‘TabsComponent’ that has an array of Tab, ‘selected’ expression as ‘EventEmitter’ by using @Output class filed decorator, and the definitions of the two functions ‘addTab’ and ‘selectTab’. In both of these functions, we are using the dependency injection concept of Angular 2.0 to add the tab and display the selected tab text on the screen respectively.

resource/my-tab-component.html

<ul>
  <li *ngFor="let tab of tabs">
    <a href="#" (click)="selectTab(tab)">{{tab.tabText}}</a>
  </li>
</ul>
<ng-content></ng-content>

Explanation of Code:
It is the HTML template for ‘my-tabs-component’ which is using *ngFor directive to iterate over the array of Tabs. Each of the displayed Tab has a hyperlink which has the HTML click event binding with the ‘selectTab (tab)’ function that selects the tab text and display it on the screen.

assets/styles.css

h3 {
  color: #369;
  font-family: Georgia, Helvetica, sans-serif;
  font-size: 150%;
}
p {
  color: #969;
  font-family: Georgia, Helvetica, sans-serif;
  font-size: 150%;
}
body {
  margin: 2em;
}

body, button {
	color: #269;
	font-family: Georgia, Helvetica, sans-serif;
}

Explanation of Code:
It is the stylesheet used to style the text on the web page of the app.

Index.html

<html>
<head>
  <base href="/">
<title>Angular 2 Tab Component</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/styles.css">
<!-- 1. Load libraries --><!-- Poly-fills for the older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<link rel="stylesheet" 
      href="node_modules/bootstrap/dist/css/bootstrap.min.css">
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
      System.import('app').catch(
    		  function(err){ 
    			  console.error(err); 
    			  }
    		  );
</script>
</head>
<!-- 3. Display the application -->
<body>
		<my-tab-app>A moment please...</my-tab-app>
</body>
</html>

Explanation of Code:
It is the ‘index.html’ file that has the ‘my-tab-app’ tag in its body section i.e. selector of ‘app-component’ to load and display the complete application. Here, we are including all the paths for the scripts which are required for the Angular 2.0 build as shown above.

Output
When we run the above angular 2.0 app for Tab components by executing the command ‘npm start’ on command line that has pointer to the application’s root directory ‘angular2-tab-component’ then we will observe the following output.
screenshot
Source Code for Angular 2.0 Tab component

Conclusion
In this chapter, we have built a tab component app in Angular 2.0 by using the three core concepts of Component, dependency injection and property bindings.

1 COMMENT

  1. Keeping getting an error when running ‘npm start’
    app/my-tabs-component.ts(15,11): error TS2339: Property ‘selected’ does not exist on type ‘Tab’

    app/my-tabs-component.ts(22,11): error TS2339: Property ‘selected’ does not exist on type ‘Tab’

    app/my-tabs-component.ts(24,9): error TS2339: Property ‘selected’ does not exist on type ‘Tab’

    steps to reproduce:
    unzip the source code file ‘angular2-tab-component’
    npm install
    npm start

    what am I doing wrong?

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -