During the development of the web page, it is often required to represent multiple contents within a tab control. But, like other control, AngularJS have own tab directive. But we can create a simple tab directive with the help of AngularJS.
For creating a tab directive, we first need to create a stylesheet file. For this, we first add a style file called style.css and add the following code :-
- <style>
- .leftTab {width: 200px;float: left;padding: 0 7px;}
- .leftTab li {float: left;width: 100%;}
- .leftTab li a {height: 30px;font-size: 12px;display: block;text-align: left;padding: 3px 2px;letter-spacing: 1px;}
- .leftTab li a span {line-height: 25px;}
- .leftTab li a .iconArrow {font-size: 9px;height: 10px;margin: 9px 9px 0 0;width: 10px;}
- .leftTab li .tabSelect {font-weight: 700;}
- </style>
- var CustomCtrlApp = angular.module('CustomCtrlApp', []);
Tabset.html
- <div>
- <div id="leftTab" class="leftTab" ng-style="BodyStyle">
- <ul ng-transclude></ul>
- </div>
- <div class="tab-content multiPage" ng-style="BodyStyle">
- <div class="tab-pane" ng-repeat="fvtab in tabs" ng-class="{active: fvtab.active}" fv-tab-content-transclude="fvtab">
- </div>
- </div>
- </div>
Tab.html
- <li ng-class="{active: active, disabled: disabled}" ng-show="visible">
- <a ng-click="select()" fv-tab-heading-transclude ng-class="{'tabSelect' : active}">
- <i class="iconArrow left fv-right"></i><span class="left">{{heading}}</span>
- </a>
- </li>
- CustomCtrlApp.service('TabService', ['$rootScope', function ($rootScope) {
- var tabsetScope = null;
- var hideIndex = null;
- var hide = function (index) {
- var selectedTab = tabsetScope.tabs[index];
- hideIndex = null;
- tabsetScope.hideTab(selectedTab);
- }
- this.setTabsetScope = function (rootScope) {
- tabsetScope = rootScope;
- if (hideIndex != #ff0000) {
- hide(hideIndex);
- }
- }
- this.selectTab = function (index) {
- var selectedTab = tabsetScope.tabs[index];
- tabsetScope.select(selectedTab);
- hideIndex = null;
- }
- this.hideTab = function (index) {
- if (tabsetScope == undefined) {
- hideIndex = index;
- }
- else {
- hide(index);
- hideIndex = null;
- }
- }
- this.showTab = function (index) {
- hideIndex = null;
- var selectedTab = tabsetScope.tabs[index];
- tabsetScope.showTab(selectedTab);
- }
- }]);
- CustomCtrlApp.directive("tabset", [function ($httpservice) {
- this;
- return {
- restrict: 'EA',
- transclude: true,
- replace: true,
- scope: {
- type: '@'
- },
- templateUrl: "../HTMLTemplate/Tabset.html",
- controller: function ($scope, $element, $attrs, TabService) {
- var ctrl = this, tabs = ctrl.tabs = $scope.tabs = [];
- $scope.BodyStyle = getElementMinHeight();
- ctrl.select = function (selectedTab) {
- angular.forEach(tabs, function (tab) {
- if (tab.active && tab !== selectedTab) {
- tab.active = false;
- tab.visible = true;
- tab.onDeselect();
- }
- });
- selectedTab.active = true;
- selectedTab.onSelect();
- TabService.setTabsetScope(ctrl);
- };
- ctrl.hideTab = function (selectedTab) {
- if (selectedTab != undefined) {
- selectedTab.visible = false;
- TabService.setTabsetScope(ctrl);
- }
- };
- ctrl.showTab = function (selectedTab) {
- selectedTab.visible = true;
- TabService.setTabsetScope(ctrl);
- };
- ctrl.addTab = function addTab(tab) {
- tabs.push(tab);
- // we can't run the select function on the first tab
- // since that would select it twice
- if (tabs.length === 1 && tab.active !== false) {
- tab.active = true;
- } else if (tab.active) {
- ctrl.select(tab);
- }
- else {
- tab.active = false;
- }
- };
- ctrl.removeTab = function removeTab(tab) {
- var index = tabs.indexOf(tab);
- //Select a new tab if the tab to be removed is selected and not destroyed
- if (tab.active && tabs.length > 1 && !destroyed) {
- //If this is the last tab, select the previous tab. else, the next tab.
- var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
- ctrl.select(tabs[newActiveIndex]);
- }
- tabs.splice(index, 1);
- };
- var destroyed;
- $scope.$on('$destroy', function () {
- destroyed = true;
- });
- }
- }
- }]);
- CustomCtrlApp.directive('TabContentTransclude', function () {
- return {
- restrict: 'A',
- require: '^tabset',
- link: function (scope, elm, attrs) {
- var tab = scope.$eval(attrs.TabContentTransclude);
- //Now our tab is ready to be transcluded: both the tab heading area
- //and the tab content area are loaded. Transclude 'em both.
- tab.$transcludeFn(tab.$parent, function (contents) {
- angular.forEach(contents, function (node) {
- if (isTabHeading(node)) {
- //Let tabHeadingTransclude know.
- tab.headingElement = node;
- } else {
- elm.append(node);
- }
- });
- });
- }
- };
- function isTabHeading(node) {
- return node.tagName && (
- node.hasAttribute('tab-heading') ||
- node.hasAttribute('data-tab-heading') ||
- node.tagName.toLowerCase() === 'tab-heading' ||
- node.tagName.toLowerCase() === 'data-tab-heading'
- );
- }
- });
- CustomCtrlApp.directive("tab", [function ($httpservice) {
- this;
- return {
- require: '^tabset',
- restrict: 'EA',
- replace: true,
- templateUrl: "../HTMLTemplate/Tab.html",
- transclude: true,
- scope: {
- active: '=?',
- heading: '@',
- onSelect: '&select', //This callback is called in contentHeadingTransclude
- //once it inserts the tab's content into the dom
- onDeselect: '&deselect'
- },
- controller: function () {
- //Empty controller so other directives can require being 'under' a tab
- },
- compile: function (elm, attrs, transclude) {
- return function postLink(scope, elm, attrs, tabsetCtrl) {
- scope.$watch('active', function (active) {
- if (active) {
- tabsetCtrl.select(scope);
- }
- });
- scope.disabled = false;
- scope.visible = true;
- if (attrs.disable) {
- scope.$parent.$watch($parse(attrs.disable), function (value) {
- scope.disabled = !!value;
- });
- }
- // Deprecation support of "disabled" parameter
- // fix(tab): IE9 disabled attr renders grey text on enabled tab #2677
- // This code is duplicated from the lines above to make it easy to remove once
- // the feature has been completely deprecated
- if (attrs.disabled) {
- $log.warn('Use of "disabled" attribute has been deprecated, please use "disable"');
- scope.$parent.$watch($parse(attrs.disabled), function (value) {
- scope.disabled = !!value;
- });
- }
- scope.select = function () {
- if (!scope.disabled) {
- scope.active = true;
- }
- };
- tabsetCtrl.addTab(scope);
- scope.$on('$destroy', function () {
- tabsetCtrl.removeTab(scope);
- });
- //We need to transclude later, once the content container is ready.
- //when this link happens, we're inside a tab heading.
- scope.$transcludeFn = transclude;
- };
- }
- }
- }]);
- CustomCtrlApp.directive('TabHeadingTransclude', [function () {
- return {
- restrict: 'A',
- require: '^tab',
- link: function (scope, elm, attrs, tabCtrl) {
- scope.$watch('headingElement', function updateHeadingElement(heading) {
- if (heading) {
- elm.html('');
- elm.append(heading);
- }
- });
- }
- };
- }]);
Now, add another html file named TabDemo.html and write down the following code:
- <!DOCTYPE html>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Sample of Tab Directive Demostration</title>
- <style>
- .leftTab {width: 200px;float: left;padding: 0 7px;}
- .leftTab li {float: left;width: 100%;}
- .leftTab li a {height: 30px;font-size: 12px;display: block;text-align: left;padding: 3px 2px;letter-spacing: 1px;}
- .leftTab li a span {line-height: 25px;}
- .leftTab li a .iconArrow {font-size: 9px;height: 10px;margin: 9px 9px 0 0;width: 10px;}
- .leftTab li .tabSelect {font-weight: 700;}
- </style>
- <script src="../Scripts/angular.min.js"></script>
- <script src="../DirectiveScript/Tab.js"></script>
- </head>
- <body>
- <tabset>
- <tab heading="First Tab">
- This is First Tab
- </tab>
- <tab heading="Second Tab">
- This is Second Tab
- </tab>
- </tabset>
- </body>
- </html>

Former memberPosted May 12, 2017, 8:30 AM
What is difference between service and factories as per your thinking ? plzz explian here if possible.
Sr KarthigaPosted Apr 19, 2016, 10:57 PM
Nice explanation
Pradeep SahooPosted Jan 28, 2016, 7:42 PM
Good share
Santhakumar MunuswamyPosted Jan 27, 2016, 2:08 PM
Thanks for nice share
Pankaj Kumar ChoudharyPosted Jan 27, 2016, 11:36 AM
Nice Article Sir..........
Arul RPosted Jan 27, 2016, 8:34 AM
Nice share
Ankit BansalPosted Jan 27, 2016, 6:16 AM
Nice share..thanks..
Humayun Kabir MamunPosted Jan 27, 2016, 12:33 AM
Nice...
Muhammad Aqib ShehzadPosted Jan 26, 2016, 1:33 PM
thanks for sharing nice article
Shashangka ShekharPosted Jan 26, 2016, 12:34 PM
Nice,Thanks :)
Mr ShanawarPosted Jan 26, 2016, 12:07 PM
Nice , thanks for this artical