UNPKG

kibana-123

Version:

Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic

280 lines (260 loc) 8.08 kB
/** * @ngdoc overview * @name ui.bootstrap.tabs * * @description * AngularJS version of the tabs directive. */ angular.module('ui.bootstrap.tabs', []) .controller('TabsetController', ['$scope', function TabsetCtrl($scope) { var ctrl = this, tabs = ctrl.tabs = $scope.tabs = []; ctrl.select = function(selectedTab) { angular.forEach(tabs, function(tab) { if (tab.active && tab !== selectedTab) { tab.active = false; tab.onDeselect(); } }); selectedTab.active = true; selectedTab.onSelect(); }; 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 = true; } else if (tab.active) { ctrl.select(tab); } }; 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; }); }]) /** * @ngdoc directive * @name ui.bootstrap.tabs.directive:tabset * @restrict EA * * @description * Tabset is the outer container for the tabs directive * * @param {boolean=} vertical Whether or not to use vertical styling for the tabs. * @param {boolean=} justified Whether or not to use justified styling for the tabs. * * @example <example module="ui.bootstrap"> <file name="index.html"> <tabset> <tab heading="Tab 1"><b>First</b> Content!</tab> <tab heading="Tab 2"><i>Second</i> Content!</tab> </tabset> <hr /> <tabset vertical="true"> <tab heading="Vertical Tab 1"><b>First</b> Vertical Content!</tab> <tab heading="Vertical Tab 2"><i>Second</i> Vertical Content!</tab> </tabset> <tabset justified="true"> <tab heading="Justified Tab 1"><b>First</b> Justified Content!</tab> <tab heading="Justified Tab 2"><i>Second</i> Justified Content!</tab> </tabset> </file> </example> */ .directive('tabset', function() { return { restrict: 'EA', transclude: true, replace: true, scope: { type: '@' }, controller: 'TabsetController', templateUrl: 'template/tabs/tabset.html', link: function(scope, element, attrs) { scope.vertical = angular.isDefined(attrs.vertical) ? scope.$parent.$eval(attrs.vertical) : false; scope.justified = angular.isDefined(attrs.justified) ? scope.$parent.$eval(attrs.justified) : false; } }; }) /** * @ngdoc directive * @name ui.bootstrap.tabs.directive:tab * @restrict EA * * @param {string=} heading The visible heading, or title, of the tab. Set HTML headings with {@link ui.bootstrap.tabs.directive:tabHeading tabHeading}. * @param {string=} select An expression to evaluate when the tab is selected. * @param {boolean=} active A binding, telling whether or not this tab is selected. * @param {boolean=} disabled A binding, telling whether or not this tab is disabled. * * @description * Creates a tab with a heading and content. Must be placed within a {@link ui.bootstrap.tabs.directive:tabset tabset}. * * @example <example module="ui.bootstrap"> <file name="index.html"> <div ng-controller="TabsDemoCtrl"> <button class="btn btn-small" ng-click="items[0].active = true"> Select item 1, using active binding </button> <button class="btn btn-small" ng-click="items[1].disabled = !items[1].disabled"> Enable/disable item 2, using disabled binding </button> <br /> <tabset> <tab heading="Tab 1">First Tab</tab> <tab select="alertMe()"> <tab-heading><i class="icon-bell"></i> Alert me!</tab-heading> Second Tab, with alert callback and html heading! </tab> <tab ng-repeat="item in items" heading="{{item.title}}" disabled="item.disabled" active="item.active"> {{item.content}} </tab> </tabset> </div> </file> <file name="script.js"> function TabsDemoCtrl($scope) { $scope.items = [ { title:"Dynamic Title 1", content:"Dynamic Item 0" }, { title:"Dynamic Title 2", content:"Dynamic Item 1", disabled: true } ]; $scope.alertMe = function() { setTimeout(function() { alert("You've selected the alert tab!"); }); }; }; </file> </example> */ /** * @ngdoc directive * @name ui.bootstrap.tabs.directive:tabHeading * @restrict EA * * @description * Creates an HTML heading for a {@link ui.bootstrap.tabs.directive:tab tab}. Must be placed as a child of a tab element. * * @example <example module="ui.bootstrap"> <file name="index.html"> <tabset> <tab> <tab-heading><b>HTML</b> in my titles?!</tab-heading> And some content, too! </tab> <tab> <tab-heading><i class="icon-heart"></i> Icon heading?!?</tab-heading> That's right. </tab> </tabset> </file> </example> */ .directive('tab', ['$parse', function($parse) { return { require: '^tabset', restrict: 'EA', replace: true, templateUrl: 'template/tabs/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; if ( attrs.disabled ) { 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; }; } }; }]) .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); } }); } }; }]) .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' ); } }) ;