UNPKG

thalassa-aqueduct

Version:

Dynamic haproxy load balancer and configuration. Part of Thalassa

300 lines (279 loc) 9.24 kB
/** * @ngdoc overview * @name ui.bootstrap.tabs * * @description * AngularJS version of the tabs directive. */ angular.module('ui.bootstrap.tabs', []) .directive('tabs', function() { return function() { throw new Error("The `tabs` directive is deprecated, please migrate to `tabset`. Instructions can be found at http://github.com/angular-ui/bootstrap/tree/master/CHANGELOG.md"); }; }) .controller('TabsetController', ['$scope', '$element', function TabsetCtrl($scope, $element) { var ctrl = this, tabs = ctrl.tabs = $scope.tabs = []; ctrl.select = function(tab) { angular.forEach(tabs, function(tab) { tab.active = false; }); tab.active = true; }; ctrl.addTab = function addTab(tab) { tabs.push(tab); if (tabs.length == 1) { 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 if (tab.active && tabs.length > 1) { //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); }; }]) /** * @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. * * @example <example module="ui.bootstrap"> <file name="index.html"> <tabset> <tab heading="Vertical Tab 1"><b>First</b> Content!</tab> <tab heading="Vertical 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> </file> </example> */ .directive('tabset', function() { return { restrict: 'EA', transclude: true, scope: {}, controller: 'TabsetController', templateUrl: 'template/tabs/tabset.html', link: function(scope, element, attrs) { scope.vertical = angular.isDefined(attrs.vertical) ? scope.$eval(attrs.vertical) : false; scope.type = angular.isDefined(attrs.type) ? scope.$parent.$eval(attrs.type) : 'tabs'; } }; }) /** * @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', '$http', '$templateCache', '$compile', function($parse, $http, $templateCache, $compile) { return { require: '^tabset', restrict: 'EA', replace: true, templateUrl: 'template/tabs/tab.html', transclude: true, scope: { heading: '@', onSelect: '&select' //This callback is called in contentHeadingTransclude //once it inserts the tab's content into the dom }, 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) { var getActive, setActive; scope.active = false; // default value if (attrs.active) { getActive = $parse(attrs.active); setActive = getActive.assign; scope.$parent.$watch(getActive, function updateActive(value) { if ( !!value && scope.disabled ) { setActive(scope.$parent, false); // Prevent active assignment } else { scope.active = !!value; } }); } else { setActive = getActive = angular.noop; } scope.$watch('active', function(active) { setActive(scope.$parent, active); if (active) { tabsetCtrl.select(scope); scope.onSelect(); } }); 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); }); //If the tabset sets this tab to active, set the parent scope's active //binding too. We do this so the watch for the parent's initial active //value won't overwrite what is initially set by the tabset if (scope.active) { setActive(scope.$parent, true); } //Transclude the collection of sibling elements. Use forEach to find //the heading if it exists. We don't use a directive for tab-heading //because it is problematic. Discussion @ http://git.io/MSNPwQ transclude(scope.$parent, function(clone) { //Look at every element in the clone collection. If it's tab-heading, //mark it as that. If it's not tab-heading, mark it as tab contents var contents = [], heading; angular.forEach(clone, function(el) { //See if it's a tab-heading attr or element directive //First make sure it's a normal element, one that has a tagName if (el.tagName && (el.hasAttribute("tab-heading") || el.hasAttribute("data-tab-heading") || el.tagName.toLowerCase() == "tab-heading" || el.tagName.toLowerCase() == "data-tab-heading" )) { heading = el; } else { contents.push(el); } }); //Share what we found on the scope, so our tabHeadingTransclude and //tabContentTransclude directives can find out what the heading and //contents are. if (heading) { scope.headingElement = angular.element(heading); } scope.contentElement = angular.element(contents); }); }; } }; }]) .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', ['$parse', function($parse) { return { restrict: 'A', require: '^tabset', link: function(scope, elm, attrs, tabsetCtrl) { scope.$watch($parse(attrs.tabContentTransclude), function(tab) { elm.html(''); if (tab) { elm.append(tab.contentElement); } }); } }; }]) ;