Build a Tabs Directive in AngularJS

Hi Guys,

In this blog you can find how to design a custom tab using AngularJS directive.

Lets jump directly how directive is constructed for this.
Before this you must be knowing about ngTransclude.

Directive that marks the insertion point for the transcluded DOM of the nearest parent directive that uses transclusion.

You can specify that you want to insert a named transclusion slot, instead of the default slot, by providing the slot name as the value of the ng-transclude or ng-transclude-slot attribute.

Any existing content of the element that this directive is placed on will be removed before the transcluded content is inserted.

For reference please visit AngularJS site https://docs.angularjs.org/api/ng/directive/ngTransclude

Coming back to our implementation you can see in index.html following code

<tab-body>
 <ng-tab class="tab" ng-tab-name="Tab 1">
  <ng-tab-body class="tab-body">tab 1 body</ng-tab-body>
 </ng-tab>
 
 <ng-tab class="tab" ng-tab-name="Tab 2">
  <ng-tab-body class="tab-body">tab 2 body</ng-tab-body>
 </ng-tab>
 <ng-tab class="tab" ng-tab-name="Tab 3">
  <ng-tab-body class="tab-body">tab 3 body</ng-tab-body>
 </ng-tab>
</tab-body> 

1. tab-body : This is a parent directive which contains all the tabs and it makes first tab selected whenever page loads.

2. ng-tab : This directive helps to build tab. ng-tab has scope ng-tab-name which is used to set tab name.

3. ng-tab-body: This is the body for main tab.

In ng-tab directive ng-tab-body is transcluded in html template.

template:"<div class="tabLink" ng-click="showTab()">
<a href="https://www.blogger.com/blogger.g?blogID=409533220043821728#">{{ngTabName}}</a></div>
<div id="activeTab_{{id}}" ng-show="showTab" ng-transclude="ngTabBody">
</div>"

When the page loads ng-tab directive finds transclude option which includes html inside the directive and returns html template.

You can find implementation code below.

index.html
<html ng-app="simpleDirective">
<head>
<script src="angular.min.js"></script>
<script src="jquery.js"></script>
<script src="app.js"></script>
</head>
<body style="margin:0;padding:0;">
<div class="middleContent">
<tab-body>
 <ng-tab class="tab" ng-tab-name="Tab 1">
  <ng-tab-body class="tab-body">tab 1 body</ng-tab-body>
 </ng-tab>
 
 <ng-tab class="tab" ng-tab-name="Tab 2">
  <ng-tab-body class="tab-body">tab 2 body</ng-tab-body>
 </ng-tab>
 <ng-tab class="tab" ng-tab-name="Tab 3">
  <ng-tab-body class="tab-body">tab 3 body</ng-tab-body>
 </ng-tab>
</tab-body> 
</div>
</body>
</html>
app.js
var app = angular.module('simpleDirective', []);
app.directive("ngTab", function(){
   
 return{
  restrict: "E",
  transclude:true,
  scope:{
   ngTabName:"@",
   ngTabBody:"@",
   ngActiveTab:"@"
  },
  controller:function ( $scope, $element, $attrs ){
   $scope.id;
   $scope.showTab = function(){
    $("div[id^='activeTab_']").each(function(){
     this.parentElement.classList.remove("active");
     $(this).hide();
    });
    $("#activeTab_"+$scope.id).show();
    $("#activeTab_"+$scope.id).parent().addClass("active");
   };
  },
  link: function($scope, element, attrs){
   $scope.id = $scope.$id;
  },
  template:"<div class="tabLink" ng-click="showTab()">
<a href="https://www.blogger.com/blogger.g?blogID=409533220043821728#">{{ngTabName}}</a></div>
<div id="activeTab_{{id}}" ng-show="showTab" ng-transclude="ngTabBody">
</div>"
 }
});

app.directive("tabBody", function(){
 return {
  restrict: "E",
  compile: function(element){
   angular.element(window).on("load",function(){
    var isFirst = true;
    var id;
    var classNames = element.children()[0].className;
    element.children()[0].className = classNames+" active";
    console.log(element);
    $("div[id^='activeTab_']").each(function(){
     if(isFirst){
      id = this.id;
      isFirst = false;
     }
     $(this).hide();
    });
    $("#"+id).show();
   });
  }
 }
});
stylesheet 
.tab{
 float:left;
 border-radius: 7px;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
 margin-right:5px;
}

.tab:hover{
 background-color:lightblue;
}


.tab .tabLink{
 padding:10px;
 radius:4px;
}

.tab-body{
     border-top: 1px solid lightblue;
    width: 90%;
    position: absolute;
    padding: 10px;
    height: 100%;
    margin: 0 auto;
    left: 0;
    right: 0;
}

.tab a{
 text-decoration: inherit;
}

.active{
 background:lightblue
}

.middleContent{
 margin:0 auto;
 width:90%;
 background:white;
 height:100%;
 padding:10px;
}

body{
 background:lightgrey;
}








Good Day :)

Post a Comment

1 Comments