AngularJs is what html would have had been if it was to build dynamic web applications. In this lesson we will take Bootstrap’s tab component and make it dynamic using angularjs and build browser like tabs.

This will be a comprehensive and simple tutorial and only requires you to have a basic knowledge of Bootstrap and AngularJs.

Features

Included

Add a new tab

Close a tab

Select a tab

Excluded

Dragging a tab

Automatic resizing

DEMO DOWNLOAD

Set up HTML

Include Bootstrap css and angularjs.You can download the Bootstrap bundle from here. Also include style.css and app.js, we will bulild them as we go along this tutorial.

As you can see we are using Boottraps tabpanel. Bellow there is only one tab and a content section.

If you run the below code you’ll find a static tabpanel with a tab as Home.

index.html

<!DOCTYPE html>

html >

head >

link href = "css/bootstrap.min.css" rel = "stylesheet" media = "screen" / >

link href = "css/bootstrap-theme.min.css" rel = "stylesheet" media = "screen" / >

link href = "css/style.css" rel = "stylesheet" media = "screen" / >

/ head >

body >

= "tabpanel" > div role

ul class = "nav nav-tabs" role = "tablist" > role

= "presentation" >< target = "#tab" aria-controls = "home" role = "tab" data-toggle = "tab" > li role>< a data-aria-controlsroledata-toggle / >< / li > a >

/ ul >

div class = "tab-content" >

= "tabpanel" class = "tab-pane active" id = "tab" > div role



/ div >

/ div >

/ div >

script src = "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js" >< / >< / script > >< script >

script src = "js/app.js" >< / script > >

/ body >

/ html > Home

Setting up angular app

Next we setup the skeleton for our Angular app in app.js . We have declared an angular module as tabDemo .

We have a controller named tabCtrl .

$scope.tabs is an array of objects that holds the information on tabs. We will be looping over this array using ng-repeat . As of now it holds only one object, this will be the default tab on load.

We have defined two functions $scope.addTab() and $scope.deleteTab() for adding and removing tabs respectively, we will write the functionality for them further in this post.

app.js

( function ( ) {

angular. module ( 'tabDemo' , [ ] )



. controller ( 'tabCtrl' , [ '$scope' , function ( $scope ) {

/** holds tabs, we will perform repeat on this **/

$scope. tabs = [ {

id : 0 ,

content : 'This is a default tab on load'

} ]



/** Function to add a new tab **/

$scope. addTab = function ( ) {



}



/** Function to delete a tab **/

$scope. deleteTab = function ( ) {



}

} ] )

} ) ( )

Adding a new tab

First we repeat the li element on $scope.tabs.To do this add ng-repeat="tab in tabs on li element inside ‘nav-tabs’.

Next we add one more static li element as our add tab button in our markup. We call addTab() function on ng-click.

index.html

ul class = "nav nav-tabs" role = "tablist" > role

= "presentation" ng-repeat = "tab in tabs" > li roleng-repeat <!-- repeat on tabs -->

target = "#tab" aria-controls = "home" role = "tab" data-toggle = "tab" > a data-aria-controlsroledata-toggle / a >

/ li >

= "presentation" ng-click = "addTab()" > li roleng-click <!-- add tab hook -->

= "home" role = "tab" data-toggle = "tab" > a aria-controlsroledata-toggle / a >

/ li >

/ ul > Home( + )

To keep track of the tabs selected and added we will define a counter that starts from 1 and and every time a tab is added we increment it by one and then assign the counter value to the ‘id’ key of that object of the $scope.tabs array.

$scope.addTab() function increments the counter by one and pushes a new object(ie a new tab) into the $scope.tabs array.

app.js

$scope. counter = 1 ;

/** Function to add a new tab **/

$scope. addTab = function ( ) {

$scope. counter ++;

$scope. tabs . push ( { id : $scope. counter , content : 'Any Content' } ) ;

}

Select tab on click

Now that we can add new tabs dynamically, we have to allow user to select different tabs and display relavent content depending on the tab selected.

‘ng-repeat’ of AngularJs provides us with an ‘$index’ variable that holds the offset of the element starting from 0.

As we are repeating over an array it will also represent the index of the array.

Now we define a variable as $scope.selectedTab which defaults to 0. We assign it the value of ‘$index’ of the tab clicked on.

To do this we create a function in our controller $scope.selectTab($index) and then call the function on click of any tab, passing ‘$index’ as a parameter, using ‘ng-click’ and then assigning $scope.selectedTab = $index .

Then using ng-class we will set the clicked element to active by adding .active class provided by Bootstrap.

Add the below code to the repeating element.

ng-click="selectTab($index)" ng-class="{'active':selectedTab == $index}"

We will show the id and content of the selected tab using tabs[selectedTab].id and tabs[selectedTab].content . selectedTab is the index of the tabs array ofcourse.

index.html



...

= "presentation" ng-repeat = "tab in tabs" ng-click = "selectTab($index)" ng- class = "{'active':selectedTab == $index}" > li roleng-repeatng-clickng-

target = "#tab" aria-controls = "home" role = "tab" data-toggle = "tab" > a data-aria-controlsroledata-toggle / a >

/ li >

...

.....

div class = "tab-content" >

= "tabpanel" class = "tab-pane active" id = "tab" > div role

h1 > / h1 >

h3 > / h3 >

/ div >

/ div > ........Tab {{tab.id}}........Tab {{tabs[selectedTab].id}}Content:- {{tabs[selectedTab].content}}

Adding $scope.selectTab() function to our controller.

app.js

...

..

$scope. selectedTab = 0 ; //set selected tab to the 1st by default.



/** Function to set selectedTab **/

$scope. selectTab = function ( index ) {

$scope. selectedTab = index ;

}

..

...

Closing a tab

Using Bootstarp’s glyphicons we will add a close icon to our tabs and on click of it we will call $scope.deleteTab($index) function passing $index as a parameter, using ‘ng-click’.

index.html



..

= "presentation" ng-repeat = "tab in tabs" ng-click = "selectTab($index)" ng- class = "{'active':selectedTab == $index}" > li roleng-repeatng-clickng-

target = "#tab" aria-controls = "home" role = "tab" data-toggle = "tab" > a data-aria-controlsroledata-toggle = "deleteTab($index)" class = "glyphicon glyphicon-remove" >< / >< / a > span ng-click>< span >

/ li >

....

... ......Tab {{tab.id}}.......

This is what our deleteTab function looks like. We just remove the object on that index.

app.js

....

.....

/** Function to delete a tab **/

$scope. deleteTab = function ( index ) {

$scope. tabs . splice ( index , 1 ) ; //remove the object from the array based on index

}

...

..

One more thing we need to do is when ever we add a new tab that tab should get active immediately, as it happens for browsers.

To do that, we need to set the $scope.selectedTab variable to the length of the $scope.tabs array minus one.

So now our $scope.addTab() function will look like this.

app.js

...

...

/** Function to add a new tab **/

$scope. addTab = function ( ) {

$scope. counter ++;

$scope. tabs . push ( { id : $scope. counter , content : 'Any Content' } ) ;

$scope. selectedTab = $scope. tabs . length - 1 ; //set the newly added tab active.

}

...

....

Finally some css

style.css

.nav-tabs > li > a {

cursor : pointer ;

}



.nav-tabs li a span : hover {

color : red ;

cursor : pointer ;

}

app.js and index.html after completion

index.html

<!DOCTYPE html>

html >

head >

link href = "css/bootstrap.min.css" rel = "stylesheet" media = "screen" / >

link href = "css/bootstrap-theme.min.css" rel = "stylesheet" media = "screen" / >

link href = "css/style.css" rel = "stylesheet" media = "screen" / >

/ head >

= "tabDemo" > body ng-app

= "tabpanel" ng-controller = "tabCtrl" > div roleng-controller

ul class = "nav nav-tabs" role = "tablist" > role

= "presentation" ng-repeat = "tab in tabs" ng-click = "selectTab($index)" ng- class = "{'active':selectedTab == $index}" > li roleng-repeatng-clickng-

target = "#tab" aria-controls = "home" role = "tab" data-toggle = "tab" > a data-aria-controlsroledata-toggle = "deleteTab($index)" class = "glyphicon glyphicon-remove" >< / >< / a > span ng-click>< span >

/ li >

= "presentation" ng-click = "addTab()" > li roleng-click

= "home" role = "tab" data-toggle = "tab" > a aria-controlsroledata-toggle / a >

/ li >

/ ul >

div class = "tab-content" >

= "tabpanel" class = "tab-pane active" id = "tab" > div role

h1 > / h1 >

h3 > / h3 >

/ div >

/ div >

/ div >

script src = "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.js" >< / script > >

script src = "js/app.js" >< / script > >

/ body >

/ html > Tab {{tab.id}}( + )Tab {{tabs[selectedTab].id}}Content:- {{tabs[selectedTab].content}}

app.js

( function ( ) {

angular. module ( 'tabDemo' , [ ] )



. controller ( 'tabCtrl' , [ '$scope' , function ( $scope ) {

/** holds tabs, we will perform repeat on this **/

$scope. tabs = [ {

id : 1 ,

content : 'This is a default tab on load'

} ]



$scope. counter = 1 ;

/** Function to add a new tab **/

$scope. addTab = function ( ) {

$scope. counter ++;

$scope. tabs . push ( { id : $scope. counter , content : 'Any Content' } ) ;

$scope. selectedTab = $scope. tabs . length - 1 ; //set the newly added tab active.

}



/** Function to delete a tab **/

$scope. deleteTab = function ( index ) {

$scope. tabs . splice ( index , 1 ) ; //remove the object from the array based on index

}



$scope. selectedTab = 0 ; //set selected tab to the 1st by default.



/** Function to set selectedTab **/

$scope. selectTab = function ( index ) {

$scope. selectedTab = index ;

}

} ] )

} ) ( )

DEMO DOWNLOAD

Conclusion

Tabs improve the layout of your application and make it user friendly. Bootstrap provides us with a nice layout for static tabs, but using the power of AngularJs we can make them dynamic and build browser like, dynamic tabs, as we did in this tutorial.

Go ahead and try this in your future projects.