Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit c1e4bb7

Browse files
committed
feat(paging): factor out common controller code
- Create paging factory for creating common controller for the pagination and pager components
1 parent 8bfeda0 commit c1e4bb7

File tree

3 files changed

+191
-175
lines changed

3 files changed

+191
-175
lines changed

Diff for: src/pager/pager.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
angular.module('ui.bootstrap.pager', ['ui.bootstrap.pagination'])
1+
angular.module('ui.bootstrap.pager', ['ui.bootstrap.paging'])
2+
3+
.controller('UibPagerController', ['$scope', '$attrs', 'uibPaging', 'uibPagerConfig', function($scope, $attrs, uibPaging, uibPagerConfig) {
4+
$scope.align = angular.isDefined($attrs.align) ? $scope.$parent.$eval($attrs.align) : uibPagerConfig.align;
5+
6+
uibPaging.create(this, $scope, $attrs);
7+
}])
28

39
.constant('uibPagerConfig', {
410
itemsPerPage: 10,
@@ -7,7 +13,7 @@ angular.module('ui.bootstrap.pager', ['ui.bootstrap.pagination'])
713
align: true
814
})
915

10-
.directive('uibPager', ['uibPagerConfig', function(pagerConfig) {
16+
.directive('uibPager', ['uibPagerConfig', function(uibPagerConfig) {
1117
return {
1218
scope: {
1319
totalItems: '=',
@@ -16,7 +22,7 @@ angular.module('ui.bootstrap.pager', ['ui.bootstrap.pagination'])
1622
ngDisabled: '='
1723
},
1824
require: ['uibPager', '?ngModel'],
19-
controller: 'UibPaginationController',
25+
controller: 'UibPagerController',
2026
controllerAs: 'pager',
2127
templateUrl: function(element, attrs) {
2228
return attrs.templateUrl || 'uib/template/pager/pager.html';
@@ -29,8 +35,7 @@ angular.module('ui.bootstrap.pager', ['ui.bootstrap.pagination'])
2935
return; // do nothing if no ng-model
3036
}
3137

32-
scope.align = angular.isDefined(attrs.align) ? scope.$parent.$eval(attrs.align) : pagerConfig.align;
33-
paginationCtrl.init(ngModelCtrl, pagerConfig);
38+
paginationCtrl.init(ngModelCtrl, uibPagerConfig);
3439
}
3540
};
3641
}]);

Diff for: src/pagination/pagination.js

+96-170
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,110 @@
1-
angular.module('ui.bootstrap.pagination', [])
2-
.controller('UibPaginationController', ['$scope', '$attrs', '$parse', function($scope, $attrs, $parse) {
3-
var self = this,
4-
ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl
5-
setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;
6-
7-
this.init = function(ngModelCtrl_, config) {
8-
ngModelCtrl = ngModelCtrl_;
9-
this.config = config;
10-
11-
ngModelCtrl.$render = function() {
12-
self.render();
1+
angular.module('ui.bootstrap.pagination', ['ui.bootstrap.paging'])
2+
.controller('UibPaginationController', ['$scope', '$attrs', '$parse', 'uibPaging', 'uibPaginationConfig', function($scope, $attrs, $parse, uibPaging, uibPaginationConfig) {
3+
var ctrl = this;
4+
// Setup configuration parameters
5+
var maxSize = angular.isDefined($attrs.maxSize) ? $scope.$parent.$eval($attrs.maxSize) : uibPaginationConfig.maxSize,
6+
rotate = angular.isDefined($attrs.rotate) ? $scope.$parent.$eval($attrs.rotate) : uibPaginationConfig.rotate,
7+
forceEllipses = angular.isDefined($attrs.forceEllipses) ? $scope.$parent.$eval($attrs.forceEllipses) : uibPaginationConfig.forceEllipses,
8+
boundaryLinkNumbers = angular.isDefined($attrs.boundaryLinkNumbers) ? $scope.$parent.$eval($attrs.boundaryLinkNumbers) : uibPaginationConfig.boundaryLinkNumbers;
9+
$scope.boundaryLinks = angular.isDefined($attrs.boundaryLinks) ? $scope.$parent.$eval($attrs.boundaryLinks) : uibPaginationConfig.boundaryLinks;
10+
$scope.directionLinks = angular.isDefined($attrs.directionLinks) ? $scope.$parent.$eval($attrs.directionLinks) : uibPaginationConfig.directionLinks;
11+
12+
uibPaging.create(this, $scope, $attrs);
13+
14+
if ($attrs.maxSize) {
15+
$scope.$parent.$watch($parse($attrs.maxSize), function(value) {
16+
maxSize = parseInt(value, 10);
17+
ctrl.render();
18+
});
19+
}
20+
21+
// Create page object used in template
22+
function makePage(number, text, isActive) {
23+
return {
24+
number: number,
25+
text: text,
26+
active: isActive
1327
};
28+
}
1429

15-
if ($attrs.itemsPerPage) {
16-
$scope.$parent.$watch($parse($attrs.itemsPerPage), function(value) {
17-
self.itemsPerPage = parseInt(value, 10);
18-
$scope.totalPages = self.calculateTotalPages();
19-
updatePage();
20-
});
21-
} else {
22-
this.itemsPerPage = config.itemsPerPage;
23-
}
30+
function getPages(currentPage, totalPages) {
31+
var pages = [];
2432

25-
$scope.$watch('totalItems', function(newTotal, oldTotal) {
26-
if (angular.isDefined(newTotal) || newTotal !== oldTotal) {
27-
$scope.totalPages = self.calculateTotalPages();
28-
updatePage();
29-
}
30-
});
31-
};
32-
33-
this.calculateTotalPages = function() {
34-
var totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage);
35-
return Math.max(totalPages || 0, 1);
36-
};
33+
// Default page limits
34+
var startPage = 1, endPage = totalPages;
35+
var isMaxSized = angular.isDefined(maxSize) && maxSize < totalPages;
3736

38-
this.render = function() {
39-
$scope.page = parseInt(ngModelCtrl.$viewValue, 10) || 1;
40-
};
37+
// recompute if maxSize
38+
if (isMaxSized) {
39+
if (rotate) {
40+
// Current page is displayed in the middle of the visible ones
41+
startPage = Math.max(currentPage - Math.floor(maxSize / 2), 1);
42+
endPage = startPage + maxSize - 1;
4143

42-
$scope.selectPage = function(page, evt) {
43-
if (evt) {
44-
evt.preventDefault();
45-
}
44+
// Adjust if limit is exceeded
45+
if (endPage > totalPages) {
46+
endPage = totalPages;
47+
startPage = endPage - maxSize + 1;
48+
}
49+
} else {
50+
// Visible pages are paginated with maxSize
51+
startPage = (Math.ceil(currentPage / maxSize) - 1) * maxSize + 1;
4652

47-
var clickAllowed = !$scope.ngDisabled || !evt;
48-
if (clickAllowed && $scope.page !== page && page > 0 && page <= $scope.totalPages) {
49-
if (evt && evt.target) {
50-
evt.target.blur();
53+
// Adjust last page if limit is exceeded
54+
endPage = Math.min(startPage + maxSize - 1, totalPages);
5155
}
52-
ngModelCtrl.$setViewValue(page);
53-
ngModelCtrl.$render();
5456
}
55-
};
56-
57-
$scope.getText = function(key) {
58-
return $scope[key + 'Text'] || self.config[key + 'Text'];
59-
};
6057

61-
$scope.noPrevious = function() {
62-
return $scope.page === 1;
63-
};
64-
65-
$scope.noNext = function() {
66-
return $scope.page === $scope.totalPages;
67-
};
58+
// Add page number links
59+
for (var number = startPage; number <= endPage; number++) {
60+
var page = makePage(number, number, number === currentPage);
61+
pages.push(page);
62+
}
6863

69-
function updatePage() {
70-
setNumPages($scope.$parent, $scope.totalPages); // Readonly variable
64+
// Add links to move between page sets
65+
if (isMaxSized && maxSize > 0 && (!rotate || forceEllipses || boundaryLinkNumbers)) {
66+
if (startPage > 1) {
67+
if (!boundaryLinkNumbers || startPage > 3) { //need ellipsis for all options unless range is too close to beginning
68+
var previousPageSet = makePage(startPage - 1, '...', false);
69+
pages.unshift(previousPageSet);
70+
}
71+
if (boundaryLinkNumbers) {
72+
if (startPage === 3) { //need to replace ellipsis when the buttons would be sequential
73+
var secondPageLink = makePage(2, '2', false);
74+
pages.unshift(secondPageLink);
75+
}
76+
//add the first page
77+
var firstPageLink = makePage(1, '1', false);
78+
pages.unshift(firstPageLink);
79+
}
80+
}
7181

72-
if ($scope.page > $scope.totalPages) {
73-
$scope.selectPage($scope.totalPages);
74-
} else {
75-
ngModelCtrl.$render();
82+
if (endPage < totalPages) {
83+
if (!boundaryLinkNumbers || endPage < totalPages - 2) { //need ellipsis for all options unless range is too close to end
84+
var nextPageSet = makePage(endPage + 1, '...', false);
85+
pages.push(nextPageSet);
86+
}
87+
if (boundaryLinkNumbers) {
88+
if (endPage === totalPages - 2) { //need to replace ellipsis when the buttons would be sequential
89+
var secondToLastPageLink = makePage(totalPages - 1, totalPages - 1, false);
90+
pages.push(secondToLastPageLink);
91+
}
92+
//add the last page
93+
var lastPageLink = makePage(totalPages, totalPages, false);
94+
pages.push(lastPageLink);
95+
}
96+
}
7697
}
98+
return pages;
7799
}
100+
101+
var originalRender = this.render;
102+
this.render = function() {
103+
originalRender();
104+
if ($scope.page > 0 && $scope.page <= $scope.totalPages) {
105+
$scope.pages = getPages($scope.page, $scope.totalPages);
106+
}
107+
};
78108
}])
79109

80110
.constant('uibPaginationConfig', {
@@ -90,9 +120,8 @@ angular.module('ui.bootstrap.pagination', [])
90120
forceEllipses: false
91121
})
92122

93-
.directive('uibPagination', ['$parse', 'uibPaginationConfig', function($parse, paginationConfig) {
123+
.directive('uibPagination', ['$parse', 'uibPaginationConfig', function($parse, uibPaginationConfig) {
94124
return {
95-
restrict: 'EA',
96125
scope: {
97126
totalItems: '=',
98127
firstText: '@',
@@ -115,110 +144,7 @@ angular.module('ui.bootstrap.pagination', [])
115144
return; // do nothing if no ng-model
116145
}
117146

118-
// Setup configuration parameters
119-
var maxSize = angular.isDefined(attrs.maxSize) ? scope.$parent.$eval(attrs.maxSize) : paginationConfig.maxSize,
120-
rotate = angular.isDefined(attrs.rotate) ? scope.$parent.$eval(attrs.rotate) : paginationConfig.rotate,
121-
forceEllipses = angular.isDefined(attrs.forceEllipses) ? scope.$parent.$eval(attrs.forceEllipses) : paginationConfig.forceEllipses,
122-
boundaryLinkNumbers = angular.isDefined(attrs.boundaryLinkNumbers) ? scope.$parent.$eval(attrs.boundaryLinkNumbers) : paginationConfig.boundaryLinkNumbers;
123-
scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : paginationConfig.boundaryLinks;
124-
scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : paginationConfig.directionLinks;
125-
126-
paginationCtrl.init(ngModelCtrl, paginationConfig);
127-
128-
if (attrs.maxSize) {
129-
scope.$parent.$watch($parse(attrs.maxSize), function(value) {
130-
maxSize = parseInt(value, 10);
131-
paginationCtrl.render();
132-
});
133-
}
134-
135-
// Create page object used in template
136-
function makePage(number, text, isActive) {
137-
return {
138-
number: number,
139-
text: text,
140-
active: isActive
141-
};
142-
}
143-
144-
function getPages(currentPage, totalPages) {
145-
var pages = [];
146-
147-
// Default page limits
148-
var startPage = 1, endPage = totalPages;
149-
var isMaxSized = angular.isDefined(maxSize) && maxSize < totalPages;
150-
151-
// recompute if maxSize
152-
if (isMaxSized) {
153-
if (rotate) {
154-
// Current page is displayed in the middle of the visible ones
155-
startPage = Math.max(currentPage - Math.floor(maxSize / 2), 1);
156-
endPage = startPage + maxSize - 1;
157-
158-
// Adjust if limit is exceeded
159-
if (endPage > totalPages) {
160-
endPage = totalPages;
161-
startPage = endPage - maxSize + 1;
162-
}
163-
} else {
164-
// Visible pages are paginated with maxSize
165-
startPage = (Math.ceil(currentPage / maxSize) - 1) * maxSize + 1;
166-
167-
// Adjust last page if limit is exceeded
168-
endPage = Math.min(startPage + maxSize - 1, totalPages);
169-
}
170-
}
171-
172-
// Add page number links
173-
for (var number = startPage; number <= endPage; number++) {
174-
var page = makePage(number, number, number === currentPage);
175-
pages.push(page);
176-
}
177-
178-
// Add links to move between page sets
179-
if (isMaxSized && maxSize > 0 && (!rotate || forceEllipses || boundaryLinkNumbers)) {
180-
if (startPage > 1) {
181-
if (!boundaryLinkNumbers || startPage > 3) { //need ellipsis for all options unless range is too close to beginning
182-
var previousPageSet = makePage(startPage - 1, '...', false);
183-
pages.unshift(previousPageSet);
184-
}
185-
if (boundaryLinkNumbers) {
186-
if (startPage === 3) { //need to replace ellipsis when the buttons would be sequential
187-
var secondPageLink = makePage(2, '2', false);
188-
pages.unshift(secondPageLink);
189-
}
190-
//add the first page
191-
var firstPageLink = makePage(1, '1', false);
192-
pages.unshift(firstPageLink);
193-
}
194-
}
195-
196-
if (endPage < totalPages) {
197-
if (!boundaryLinkNumbers || endPage < totalPages - 2) { //need ellipsis for all options unless range is too close to end
198-
var nextPageSet = makePage(endPage + 1, '...', false);
199-
pages.push(nextPageSet);
200-
}
201-
if (boundaryLinkNumbers) {
202-
if (endPage === totalPages - 2) { //need to replace ellipsis when the buttons would be sequential
203-
var secondToLastPageLink = makePage(totalPages - 1, totalPages - 1, false);
204-
pages.push(secondToLastPageLink);
205-
}
206-
//add the last page
207-
var lastPageLink = makePage(totalPages, totalPages, false);
208-
pages.push(lastPageLink);
209-
}
210-
}
211-
}
212-
return pages;
213-
}
214-
215-
var originalRender = paginationCtrl.render;
216-
paginationCtrl.render = function() {
217-
originalRender();
218-
if (scope.page > 0 && scope.page <= scope.totalPages) {
219-
scope.pages = getPages(scope.page, scope.totalPages);
220-
}
221-
};
147+
paginationCtrl.init(ngModelCtrl, uibPaginationConfig);
222148
}
223149
};
224150
}]);

0 commit comments

Comments
 (0)