This repository has been archived by the owner on Sep 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
/
tabDirective.js
139 lines (130 loc) · 4.73 KB
/
tabDirective.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* @ngdoc directive
* @name mdTab
* @module material.components.tabs
*
* @restrict E
*
* @description
* The `<md-tab>` is a nested directive used within `<md-tabs>` to specify a tab with a **label**
* and optional *view content*.
*
* If the `label` attribute is not specified, then an optional `<md-tab-label>` tag can be used to
* specify more complex tab header markup. If neither the **label** nor the **md-tab-label** are
* specified, then the nested markup of the `<md-tab>` is used as the tab header markup.
*
* Please note that if you use `<md-tab-label>`, your content **MUST** be wrapped in the
* `<md-tab-body>` tag. This is to define a clear separation between the tab content and the tab
* label.
*
* This container is used by the TabsController to show/hide the active tab's content view. This
* synchronization is automatically managed by the internal TabsController whenever the tab
* selection changes. Selection changes can be initiated via data binding changes, programmatic
* invocation, or user gestures.
*
* @param {string=} label Optional attribute to specify a simple string as the tab label
* @param {boolean=} ng-disabled If present and expression evaluates to truthy, disabled tab
* selection.
* @param {string=} md-tab-class Optional attribute to specify a class that will be applied to the
* tab's button
* @param {expression=} md-on-deselect Expression to be evaluated after the tab has been
* de-selected.
* @param {expression=} md-on-select Expression to be evaluated after the tab has been selected.
* @param {boolean=} md-active When true, sets the active tab. Note: There can only be one active
* tab at a time.
*
*
* @usage
*
* <hljs lang="html">
* <md-tab label="My Tab" md-tab-class="my-content-tab" ng-disabled md-on-select="onSelect()"
* md-on-deselect="onDeselect()">
* <h3>My Tab content</h3>
* </md-tab>
*
* <md-tab>
* <md-tab-label>
* <h3>My Tab</h3>
* </md-tab-label>
* <md-tab-body>
* <p>
* Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
* laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
* architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit
* aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione
* voluptatem sequi nesciunt.
* </p>
* </md-tab-body>
* </md-tab>
* </hljs>
*
*/
angular
.module('material.components.tabs')
.directive('mdTab', MdTab);
function MdTab () {
return {
require: '^?mdTabs',
terminal: true,
compile: function (element, attr) {
var label = firstChild(element, 'md-tab-label'),
body = firstChild(element, 'md-tab-body');
if (label.length === 0) {
label = angular.element('<md-tab-label></md-tab-label>');
if (attr.label) label.text(attr.label);
else label.append(element.contents());
if (body.length === 0) {
var contents = element.contents().detach();
body = angular.element('<md-tab-body></md-tab-body>');
body.append(contents);
}
}
element.append(label);
if (body.html()) element.append(body);
return postLink;
},
scope: {
active: '=?mdActive',
disabled: '=?ngDisabled',
select: '&?mdOnSelect',
deselect: '&?mdOnDeselect',
tabClass: '@mdTabClass'
}
};
function postLink (scope, element, attr, ctrl) {
if (!ctrl) return;
var index = ctrl.getTabElementIndex(element),
body = firstChild(element, 'md-tab-body').remove(),
label = firstChild(element, 'md-tab-label').remove(),
data = ctrl.insertTab({
scope: scope,
parent: scope.$parent,
index: index,
element: element,
template: body.html(),
label: label.html()
}, index);
scope.select = scope.select || angular.noop;
scope.deselect = scope.deselect || angular.noop;
scope.$watch('active', function (active) { if (active) ctrl.select(data.getIndex(), true); });
scope.$watch('disabled', function () { ctrl.refreshIndex(); });
scope.$watch(
function () {
return ctrl.getTabElementIndex(element);
},
function (newIndex) {
data.index = newIndex;
ctrl.updateTabOrder();
}
);
scope.$on('$destroy', function () { ctrl.removeTab(data); });
}
function firstChild (element, tagName) {
var children = element[0].children;
for (var i = 0, len = children.length; i < len; i++) {
var child = children[i];
if (child.tagName === tagName.toUpperCase()) return angular.element(child);
}
return angular.element();
}
}