11angular . module ( 'ui.bootstrap.pagination' , [ ] )
22
3- . controller ( 'PaginationController' , [ '$scope' , '$interpolate' , function ( $scope , $interpolate ) {
3+ . controller ( 'PaginationController' , [ '$scope' , '$attrs' , '$parse' , '$interpolate' , function ( $scope , $attrs , $parse , $interpolate ) {
4+ var self = this ;
45
5- this . currentPage = 1 ;
6+ this . init = function ( defaultItemsPerPage ) {
7+ if ( $attrs . itemsPerPage ) {
8+ $scope . $parent . $watch ( $parse ( $attrs . itemsPerPage ) , function ( value ) {
9+ self . itemsPerPage = parseInt ( value , 10 ) ;
10+ $scope . totalPages = self . calculateTotalPages ( ) ;
11+ } ) ;
12+ } else {
13+ this . itemsPerPage = defaultItemsPerPage ;
14+ }
15+ } ;
616
717 this . noPrevious = function ( ) {
8- return this . currentPage === 1 ;
18+ return this . page === 1 ;
919 } ;
1020 this . noNext = function ( ) {
11- return this . currentPage === $scope . numPages ;
21+ return this . page === $scope . totalPages ;
1222 } ;
1323
1424 this . isActive = function ( page ) {
15- return this . currentPage === page ;
25+ return this . page === page ;
1626 } ;
1727
18- this . reset = function ( ) {
19- $scope . pages = [ ] ;
20- this . currentPage = parseInt ( $scope . currentPage , 10 ) ;
28+ this . calculateTotalPages = function ( ) {
29+ return this . itemsPerPage < 1 ? 1 : Math . ceil ( $scope . totalItems / this . itemsPerPage ) ;
30+ } ;
2131
22- if ( this . currentPage > $scope . numPages ) {
23- $scope . selectPage ( $scope . numPages ) ;
24- }
32+ this . getAttributeValue = function ( attribute , defaultValue , interpolate ) {
33+ return angular . isDefined ( attribute ) ? ( interpolate ? $interpolate ( attribute ) ( $scope . $parent ) : $scope . $parent . $eval ( attribute ) ) : defaultValue ;
34+ } ;
35+
36+ this . render = function ( ) {
37+ this . page = parseInt ( $scope . page , 10 ) || 1 ;
38+ $scope . pages = this . getPages ( this . page , $scope . totalPages ) ;
2539 } ;
2640
27- var self = this ;
2841 $scope . selectPage = function ( page ) {
29- if ( ! self . isActive ( page ) && page > 0 && page <= $scope . numPages ) {
30- $scope . currentPage = page ;
42+ if ( ! self . isActive ( page ) && page > 0 && page <= $scope . totalPages ) {
43+ $scope . page = page ;
3144 $scope . onSelectPage ( { page : page } ) ;
3245 }
3346 } ;
3447
35- this . getAttributeValue = function ( attribute , defaultValue , interpolate ) {
36- return angular . isDefined ( attribute ) ? ( interpolate ? $interpolate ( attribute ) ( $scope . $parent ) : $scope . $parent . $eval ( attribute ) ) : defaultValue ;
37- } ;
48+ $scope . $watch ( 'totalItems' , function ( ) {
49+ $scope . totalPages = self . calculateTotalPages ( ) ;
50+ } ) ;
51+
52+ $scope . $watch ( 'totalPages' , function ( value ) {
53+ if ( $attrs . numPages ) {
54+ $scope . numPages = value ; // Readonly variable
55+ }
56+
57+ if ( self . page > value ) {
58+ $scope . selectPage ( value ) ;
59+ } else {
60+ self . render ( ) ;
61+ }
62+ } ) ;
63+
64+ $scope . $watch ( 'page' , function ( ) {
65+ self . render ( ) ;
66+ } ) ;
3867} ] )
3968
4069. constant ( 'paginationConfig' , {
70+ itemsPerPage : 10 ,
4171 boundaryLinks : false ,
4272 directionLinks : true ,
4373 firstText : 'First' ,
@@ -47,28 +77,38 @@ angular.module('ui.bootstrap.pagination', [])
4777 rotate : true
4878} )
4979
50- . directive ( 'pagination' , [ 'paginationConfig' , function ( config ) {
80+ . directive ( 'pagination' , [ '$parse' , ' paginationConfig', function ( $parse , config ) {
5181 return {
5282 restrict : 'EA' ,
5383 scope : {
54- numPages : '=' ,
55- currentPage : '=' ,
56- maxSize : '= ',
57- onSelectPage : '& '
84+ page : '=' ,
85+ totalItems : '=' ,
86+ onSelectPage : ' & ',
87+ numPages : '= '
5888 } ,
5989 controller : 'PaginationController' ,
6090 templateUrl : 'template/pagination/pagination.html' ,
6191 replace : true ,
6292 link : function ( scope , element , attrs , paginationCtrl ) {
6393
6494 // Setup configuration parameters
65- var boundaryLinks = paginationCtrl . getAttributeValue ( attrs . boundaryLinks , config . boundaryLinks ) ,
66- directionLinks = paginationCtrl . getAttributeValue ( attrs . directionLinks , config . directionLinks ) ,
67- firstText = paginationCtrl . getAttributeValue ( attrs . firstText , config . firstText , true ) ,
68- previousText = paginationCtrl . getAttributeValue ( attrs . previousText , config . previousText , true ) ,
69- nextText = paginationCtrl . getAttributeValue ( attrs . nextText , config . nextText , true ) ,
70- lastText = paginationCtrl . getAttributeValue ( attrs . lastText , config . lastText , true ) ,
71- rotate = paginationCtrl . getAttributeValue ( attrs . rotate , config . rotate ) ;
95+ var maxSize ,
96+ boundaryLinks = paginationCtrl . getAttributeValue ( attrs . boundaryLinks , config . boundaryLinks ) ,
97+ directionLinks = paginationCtrl . getAttributeValue ( attrs . directionLinks , config . directionLinks ) ,
98+ firstText = paginationCtrl . getAttributeValue ( attrs . firstText , config . firstText , true ) ,
99+ previousText = paginationCtrl . getAttributeValue ( attrs . previousText , config . previousText , true ) ,
100+ nextText = paginationCtrl . getAttributeValue ( attrs . nextText , config . nextText , true ) ,
101+ lastText = paginationCtrl . getAttributeValue ( attrs . lastText , config . lastText , true ) ,
102+ rotate = paginationCtrl . getAttributeValue ( attrs . rotate , config . rotate ) ;
103+
104+ paginationCtrl . init ( config . itemsPerPage ) ;
105+
106+ if ( attrs . maxSize ) {
107+ scope . $parent . $watch ( $parse ( attrs . maxSize ) , function ( value ) {
108+ maxSize = parseInt ( value , 10 ) ;
109+ paginationCtrl . render ( ) ;
110+ } ) ;
111+ }
72112
73113 // Create page object used in template
74114 function makePage ( number , text , isActive , isDisabled ) {
@@ -80,76 +120,79 @@ angular.module('ui.bootstrap.pagination', [])
80120 } ;
81121 }
82122
83- scope . $watch ( 'numPages + currentPage + maxSize' , function ( ) {
84- paginationCtrl . reset ( ) ;
123+ paginationCtrl . getPages = function ( currentPage , totalPages ) {
124+ var pages = [ ] ;
85125
86126 // Default page limits
87- var startPage = 1 , endPage = scope . numPages ;
88- var isMaxSized = ( angular . isDefined ( scope . maxSize ) && scope . maxSize < scope . numPages ) ;
127+ var startPage = 1 , endPage = totalPages ;
128+ var isMaxSized = ( angular . isDefined ( maxSize ) && maxSize < totalPages ) ;
89129
90130 // recompute if maxSize
91131 if ( isMaxSized ) {
92132 if ( rotate ) {
93133 // Current page is displayed in the middle of the visible ones
94- startPage = Math . max ( paginationCtrl . currentPage - Math . floor ( scope . maxSize / 2 ) , 1 ) ;
95- endPage = startPage + scope . maxSize - 1 ;
134+ startPage = Math . max ( currentPage - Math . floor ( maxSize / 2 ) , 1 ) ;
135+ endPage = startPage + maxSize - 1 ;
96136
97137 // Adjust if limit is exceeded
98- if ( endPage > scope . numPages ) {
99- endPage = scope . numPages ;
100- startPage = endPage - scope . maxSize + 1 ;
138+ if ( endPage > totalPages ) {
139+ endPage = totalPages ;
140+ startPage = endPage - maxSize + 1 ;
101141 }
102142 } else {
103143 // Visible pages are paginated with maxSize
104- startPage = ( ( Math . ceil ( paginationCtrl . currentPage / scope . maxSize ) - 1 ) * scope . maxSize ) + 1 ;
144+ startPage = ( ( Math . ceil ( currentPage / maxSize ) - 1 ) * maxSize ) + 1 ;
105145
106146 // Adjust last page if limit is exceeded
107- endPage = Math . min ( startPage + scope . maxSize - 1 , scope . numPages ) ;
147+ endPage = Math . min ( startPage + maxSize - 1 , totalPages ) ;
108148 }
109149 }
110150
111151 // Add page number links
112152 for ( var number = startPage ; number <= endPage ; number ++ ) {
113153 var page = makePage ( number , number , paginationCtrl . isActive ( number ) , false ) ;
114- scope . pages . push ( page ) ;
154+ pages . push ( page ) ;
115155 }
116156
117157 // Add links to move between page sets
118158 if ( isMaxSized && ! rotate ) {
119159 if ( startPage > 1 ) {
120160 var previousPageSet = makePage ( startPage - 1 , '...' , false , false ) ;
121- scope . pages . unshift ( previousPageSet ) ;
161+ pages . unshift ( previousPageSet ) ;
122162 }
123163
124- if ( endPage < scope . numPages ) {
164+ if ( endPage < totalPages ) {
125165 var nextPageSet = makePage ( endPage + 1 , '...' , false , false ) ;
126- scope . pages . push ( nextPageSet ) ;
166+ pages . push ( nextPageSet ) ;
127167 }
128168 }
129169
130170 // Add previous & next links
131171 if ( directionLinks ) {
132- var previousPage = makePage ( paginationCtrl . currentPage - 1 , previousText , false , paginationCtrl . noPrevious ( ) ) ;
133- scope . pages . unshift ( previousPage ) ;
172+ var previousPage = makePage ( currentPage - 1 , previousText , false , paginationCtrl . noPrevious ( ) ) ;
173+ pages . unshift ( previousPage ) ;
134174
135- var nextPage = makePage ( paginationCtrl . currentPage + 1 , nextText , false , paginationCtrl . noNext ( ) ) ;
136- scope . pages . push ( nextPage ) ;
175+ var nextPage = makePage ( currentPage + 1 , nextText , false , paginationCtrl . noNext ( ) ) ;
176+ pages . push ( nextPage ) ;
137177 }
138178
139179 // Add first & last links
140180 if ( boundaryLinks ) {
141181 var firstPage = makePage ( 1 , firstText , false , paginationCtrl . noPrevious ( ) ) ;
142- scope . pages . unshift ( firstPage ) ;
182+ pages . unshift ( firstPage ) ;
143183
144- var lastPage = makePage ( scope . numPages , lastText , false , paginationCtrl . noNext ( ) ) ;
145- scope . pages . push ( lastPage ) ;
184+ var lastPage = makePage ( totalPages , lastText , false , paginationCtrl . noNext ( ) ) ;
185+ pages . push ( lastPage ) ;
146186 }
147- } ) ;
187+
188+ return pages ;
189+ } ;
148190 }
149191 } ;
150192} ] )
151193
152194. constant ( 'pagerConfig' , {
195+ itemsPerPage : 10 ,
153196 previousText : '« Previous' ,
154197 nextText : 'Next »' ,
155198 align : true
@@ -159,9 +202,10 @@ angular.module('ui.bootstrap.pagination', [])
159202 return {
160203 restrict : 'EA' ,
161204 scope : {
162- numPages : '=' ,
163- currentPage : '=' ,
164- onSelectPage : '&'
205+ page : '=' ,
206+ totalItems : '=' ,
207+ onSelectPage :' &' ,
208+ numPages : '='
165209 } ,
166210 controller : 'PaginationController' ,
167211 templateUrl : 'template/pagination/pager.html' ,
@@ -173,6 +217,8 @@ angular.module('ui.bootstrap.pagination', [])
173217 nextText = paginationCtrl . getAttributeValue ( attrs . nextText , config . nextText , true ) ,
174218 align = paginationCtrl . getAttributeValue ( attrs . align , config . align ) ;
175219
220+ paginationCtrl . init ( config . itemsPerPage ) ;
221+
176222 // Create page object used in template
177223 function makePage ( number , text , isDisabled , isPrevious , isNext ) {
178224 return {
@@ -184,16 +230,12 @@ angular.module('ui.bootstrap.pagination', [])
184230 } ;
185231 }
186232
187- scope . $watch ( 'numPages + currentPage' , function ( ) {
188- paginationCtrl . reset ( ) ;
189-
190- // Add previous & next links
191- var previousPage = makePage ( paginationCtrl . currentPage - 1 , previousText , paginationCtrl . noPrevious ( ) , true , false ) ;
192- scope . pages . unshift ( previousPage ) ;
193-
194- var nextPage = makePage ( paginationCtrl . currentPage + 1 , nextText , paginationCtrl . noNext ( ) , false , true ) ;
195- scope . pages . push ( nextPage ) ;
196- } ) ;
233+ paginationCtrl . getPages = function ( currentPage ) {
234+ return [
235+ makePage ( currentPage - 1 , previousText , paginationCtrl . noPrevious ( ) , true , false ) ,
236+ makePage ( currentPage + 1 , nextText , paginationCtrl . noNext ( ) , false , true )
237+ ] ;
238+ } ;
197239 }
198240 } ;
199241} ] ) ;
0 commit comments