@@ -2,66 +2,103 @@ angular.module('ui.bootstrap.tabs', [])
2
2
3
3
. controller ( 'UibTabsetController' , [ '$scope' , function ( $scope ) {
4
4
var ctrl = this ,
5
- tabs = ctrl . tabs = $scope . tabs = [ ] ;
6
-
7
- ctrl . select = function ( selectedTab ) {
8
- angular . forEach ( tabs , function ( tab ) {
9
- if ( tab . active && tab !== selectedTab ) {
10
- tab . active = false ;
11
- tab . onDeselect ( ) ;
12
- selectedTab . selectCalled = false ;
5
+ oldIndex ;
6
+ ctrl . tabs = [ ] ;
7
+
8
+ ctrl . select = function ( index ) {
9
+ if ( ! destroyed ) {
10
+ var previousIndex = findTabIndex ( oldIndex ) ;
11
+ var previousSelected = ctrl . tabs [ previousIndex ] ;
12
+ if ( previousSelected ) {
13
+ previousSelected . tab . onDeselect ( ) ;
14
+ previousSelected . tab . active = false ;
15
+ }
16
+
17
+ var selected = ctrl . tabs [ index ] ;
18
+ if ( selected ) {
19
+ selected . tab . onSelect ( ) ;
20
+ selected . tab . active = true ;
21
+ ctrl . active = selected . index ;
22
+ oldIndex = selected . index ;
23
+ } else if ( ! selected && angular . isNumber ( oldIndex ) ) {
24
+ ctrl . active = null ;
25
+ oldIndex = null ;
13
26
}
14
- } ) ;
15
- selectedTab . active = true ;
16
- // only call select if it has not already been called
17
- if ( ! selectedTab . selectCalled ) {
18
- selectedTab . onSelect ( ) ;
19
- selectedTab . selectCalled = true ;
20
27
}
21
28
} ;
22
29
23
30
ctrl . addTab = function addTab ( tab ) {
24
- tabs . push ( tab ) ;
25
- // we can't run the select function on the first tab
26
- // since that would select it twice
27
- if ( tabs . length === 1 && tab . active !== false ) {
28
- tab . active = true ;
29
- } else if ( tab . active ) {
30
- ctrl . select ( tab ) ;
31
- } else {
32
- tab . active = false ;
31
+ ctrl . tabs . push ( {
32
+ tab : tab ,
33
+ index : tab . index
34
+ } ) ;
35
+ ctrl . tabs . sort ( function ( t1 , t2 ) {
36
+ if ( t1 . index > t2 . index ) {
37
+ return 1 ;
38
+ }
39
+
40
+ if ( t1 . index < t2 . index ) {
41
+ return - 1 ;
42
+ }
43
+
44
+ return 0 ;
45
+ } ) ;
46
+
47
+ if ( tab . index === ctrl . active || ! angular . isNumber ( ctrl . active ) && ctrl . tabs . length === 1 ) {
48
+ var newActiveIndex = findTabIndex ( tab . index ) ;
49
+ ctrl . select ( newActiveIndex ) ;
33
50
}
34
51
} ;
35
52
36
53
ctrl . removeTab = function removeTab ( tab ) {
37
- var index = tabs . indexOf ( tab ) ;
38
- //Select a new tab if the tab to be removed is selected and not destroyed
39
- if ( tab . active && tabs . length > 1 && ! destroyed ) {
40
- //If this is the last tab, select the previous tab. else, the next tab.
41
- var newActiveIndex = index === tabs . length - 1 ? index - 1 : index + 1 ;
42
- ctrl . select ( tabs [ newActiveIndex ] ) ;
54
+ var index = findTabIndex ( tab . index ) ;
55
+
56
+ if ( tab . index === ctrl . active ) {
57
+ var newActiveTabIndex = index === ctrl . tabs . length - 1 ?
58
+ index - 1 : index + 1 % ctrl . tabs . length ;
59
+ ctrl . select ( newActiveTabIndex ) ;
43
60
}
44
- tabs . splice ( index , 1 ) ;
61
+
62
+ ctrl . tabs . splice ( index , 1 ) ;
45
63
} ;
46
64
65
+ $scope . $watch ( 'tabset.active' , function ( val ) {
66
+ if ( angular . isNumber ( val ) && val !== oldIndex ) {
67
+ ctrl . select ( findTabIndex ( val ) ) ;
68
+ }
69
+ } ) ;
70
+
47
71
var destroyed ;
48
72
$scope . $on ( '$destroy' , function ( ) {
49
73
destroyed = true ;
50
74
} ) ;
75
+
76
+ function findTabIndex ( index ) {
77
+ for ( var i = 0 ; i < ctrl . tabs . length ; i ++ ) {
78
+ if ( ctrl . tabs [ i ] . index === index ) {
79
+ return i ;
80
+ }
81
+ }
82
+ }
51
83
} ] )
52
84
53
85
. directive ( 'uibTabset' , function ( ) {
54
86
return {
55
87
transclude : true ,
56
88
replace : true ,
57
- scope : {
89
+ scope : { } ,
90
+ bindToController : {
91
+ active : '=' ,
58
92
type : '@'
59
93
} ,
60
94
controller : 'UibTabsetController' ,
95
+ controllerAs : 'tabset' ,
61
96
templateUrl : 'uib/template/tabs/tabset.html' ,
62
97
link : function ( scope , element , attrs ) {
63
- scope . vertical = angular . isDefined ( attrs . vertical ) ? scope . $parent . $eval ( attrs . vertical ) : false ;
64
- scope . justified = angular . isDefined ( attrs . justified ) ? scope . $parent . $eval ( attrs . justified ) : false ;
98
+ scope . vertical = angular . isDefined ( attrs . vertical ) ?
99
+ scope . $parent . $eval ( attrs . vertical ) : false ;
100
+ scope . justified = angular . isDefined ( attrs . justified ) ?
101
+ scope . $parent . $eval ( attrs . justified ) : false ;
65
102
}
66
103
} ;
67
104
} )
@@ -73,8 +110,8 @@ angular.module('ui.bootstrap.tabs', [])
73
110
templateUrl : 'uib/template/tabs/tab.html' ,
74
111
transclude : true ,
75
112
scope : {
76
- active : '=?' ,
77
113
heading : '@' ,
114
+ index : '=' ,
78
115
onSelect : '&select' , //This callback is called in contentHeadingTransclude
79
116
//once it inserts the tab's content into the dom
80
117
onDeselect : '&deselect'
@@ -84,12 +121,6 @@ angular.module('ui.bootstrap.tabs', [])
84
121
} ,
85
122
controllerAs : 'tab' ,
86
123
link : function ( scope , elm , attrs , tabsetCtrl , transclude ) {
87
- scope . $watch ( 'active' , function ( active ) {
88
- if ( active ) {
89
- tabsetCtrl . select ( scope ) ;
90
- }
91
- } ) ;
92
-
93
124
scope . disabled = false ;
94
125
if ( attrs . disable ) {
95
126
scope . $parent . $watch ( $parse ( attrs . disable ) , function ( value ) {
@@ -99,7 +130,15 @@ angular.module('ui.bootstrap.tabs', [])
99
130
100
131
scope . select = function ( ) {
101
132
if ( ! scope . disabled ) {
102
- scope . active = true ;
133
+ var index ;
134
+ for ( var i = 0 ; i < tabsetCtrl . tabs . length ; i ++ ) {
135
+ if ( tabsetCtrl . tabs [ i ] . tab === scope ) {
136
+ index = i ;
137
+ break ;
138
+ }
139
+ }
140
+
141
+ tabsetCtrl . select ( index ) ;
103
142
}
104
143
} ;
105
144
@@ -135,7 +174,7 @@ angular.module('ui.bootstrap.tabs', [])
135
174
restrict : 'A' ,
136
175
require : '^uibTabset' ,
137
176
link : function ( scope , elm , attrs ) {
138
- var tab = scope . $eval ( attrs . uibTabContentTransclude ) ;
177
+ var tab = scope . $eval ( attrs . uibTabContentTransclude ) . tab ;
139
178
140
179
//Now our tab is ready to be transcluded: both the tab heading area
141
180
//and the tab content area are loaded. Transclude 'em both.
0 commit comments