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

refactor(pagination): move boundary & directions to the template #1770

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 51 additions & 89 deletions src/pagination/pagination.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
angular.module('ui.bootstrap.pagination', [])

.controller('PaginationController', ['$scope', '$attrs', '$parse', '$interpolate', function ($scope, $attrs, $parse, $interpolate) {
.controller('PaginationController', ['$scope', '$attrs', '$parse', function ($scope, $attrs, $parse) {
var self = this,
ngModelCtrl = { $setViewValue: angular.noop }, // nullModelCtrl
setNumPages = $attrs.numPages ? $parse($attrs.numPages).assign : angular.noop;

this.init = function(ngModelCtrl_, defaultItemsPerPage) {
this.init = function(ngModelCtrl_, config) {
ngModelCtrl = ngModelCtrl_;
this.config = config;

ngModelCtrl.$render = function() {
self.render();
Expand All @@ -18,52 +19,44 @@ angular.module('ui.bootstrap.pagination', [])
$scope.totalPages = self.calculateTotalPages();
});
} else {
this.itemsPerPage = defaultItemsPerPage;
this.itemsPerPage = config.itemsPerPage;
}
};

this.noPrevious = function() {
return this.page === 1;
};
this.noNext = function() {
return this.page === $scope.totalPages;
};

this.isActive = function(page) {
return this.page === page;
};

this.calculateTotalPages = function() {
var totalPages = this.itemsPerPage < 1 ? 1 : Math.ceil($scope.totalItems / this.itemsPerPage);
return Math.max(totalPages || 0, 1);
};

this.getAttributeValue = function(attribute, defaultValue, interpolate) {
return angular.isDefined(attribute) ? (interpolate ? $interpolate(attribute)($scope.$parent) : $scope.$parent.$eval(attribute)) : defaultValue;
};

this.render = function() {
this.page = parseInt(ngModelCtrl.$viewValue, 10) || 1;
if (this.page > 0 && this.page <= $scope.totalPages) {
$scope.pages = this.getPages(this.page, $scope.totalPages);
}
$scope.page = parseInt(ngModelCtrl.$viewValue, 10) || 1;
};

$scope.selectPage = function(page) {
if ( ! self.isActive(page) && page > 0 && page <= $scope.totalPages) {
if ( $scope.page !== page && page > 0 && page <= $scope.totalPages) {
ngModelCtrl.$setViewValue(page);
ngModelCtrl.$render();
}
};

$scope.getText = function( key ) {
return $scope[key + 'Text'] || self.config[key + 'Text'];
};
$scope.noPrevious = function() {
return $scope.page === 1;
};
$scope.noNext = function() {
return $scope.page === $scope.totalPages;
};

$scope.$watch('totalItems', function() {
$scope.totalPages = self.calculateTotalPages();
});

$scope.$watch('totalPages', function(value) {
setNumPages($scope.$parent, value); // Readonly variable

if ( self.page > value ) {
if ( $scope.page > value ) {
$scope.selectPage(value);
} else {
ngModelCtrl.$render();
Expand All @@ -82,34 +75,34 @@ angular.module('ui.bootstrap.pagination', [])
rotate: true
})

.directive('pagination', ['$parse', 'paginationConfig', function($parse, config) {
.directive('pagination', ['$parse', 'paginationConfig', function($parse, paginationConfig) {
return {
restrict: 'EA',
scope: {
totalItems: '='
totalItems: '=',
firstText: '@',
previousText: '@',
nextText: '@',
lastText: '@'
},
require: ['pagination', '?ngModel'],
controller: 'PaginationController',
templateUrl: 'template/pagination/pagination.html',
replace: true,
link: function(scope, element, attrs, ctrls) {
var paginationCtrl = ctrls[0], ngModel = ctrls[1];
var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1];

if (!ngModel) {
if (!ngModelCtrl) {
return; // do nothing if no ng-model
}

// Setup configuration parameters
var maxSize = paginationCtrl.getAttributeValue(attrs.maxSize, config.maxSize ),
boundaryLinks = paginationCtrl.getAttributeValue(attrs.boundaryLinks, config.boundaryLinks ),
directionLinks = paginationCtrl.getAttributeValue(attrs.directionLinks, config.directionLinks ),
firstText = paginationCtrl.getAttributeValue(attrs.firstText, config.firstText, true),
previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
lastText = paginationCtrl.getAttributeValue(attrs.lastText, config.lastText, true),
rotate = paginationCtrl.getAttributeValue(attrs.rotate, config.rotate);
var maxSize = angular.isDefined(attrs.maxSize) ? scope.$parent.$eval(attrs.maxSize) : paginationConfig.maxSize,
rotate = angular.isDefined(attrs.rotate) ? scope.$parent.$eval(attrs.rotate) : paginationConfig.rotate;
scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : paginationConfig.boundaryLinks;
scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : paginationConfig.directionLinks;

paginationCtrl.init(ngModel, config.itemsPerPage);
paginationCtrl.init(ngModelCtrl, paginationConfig);

if (attrs.maxSize) {
scope.$parent.$watch($parse(attrs.maxSize), function(value) {
Expand All @@ -119,16 +112,15 @@ angular.module('ui.bootstrap.pagination', [])
}

// Create page object used in template
function makePage(number, text, isActive, isDisabled) {
function makePage(number, text, isActive) {
return {
number: number,
text: text,
active: isActive,
disabled: isDisabled
active: isActive
};
}

paginationCtrl.getPages = function(currentPage, totalPages) {
function getPages(currentPage, totalPages) {
var pages = [];

// Default page limits
Expand Down Expand Up @@ -158,42 +150,32 @@ angular.module('ui.bootstrap.pagination', [])

// Add page number links
for (var number = startPage; number <= endPage; number++) {
var page = makePage(number, number, paginationCtrl.isActive(number), false);
var page = makePage(number, number, number === currentPage);
pages.push(page);
}

// Add links to move between page sets
if ( isMaxSized && ! rotate ) {
if ( startPage > 1 ) {
var previousPageSet = makePage(startPage - 1, '...', false, false);
var previousPageSet = makePage(startPage - 1, '...', false);
pages.unshift(previousPageSet);
}

if ( endPage < totalPages ) {
var nextPageSet = makePage(endPage + 1, '...', false, false);
var nextPageSet = makePage(endPage + 1, '...', false);
pages.push(nextPageSet);
}
}

// Add previous & next links
if (directionLinks) {
var previousPage = makePage(currentPage - 1, previousText, false, paginationCtrl.noPrevious());
pages.unshift(previousPage);

var nextPage = makePage(currentPage + 1, nextText, false, paginationCtrl.noNext());
pages.push(nextPage);
}

// Add first & last links
if (boundaryLinks) {
var firstPage = makePage(1, firstText, false, paginationCtrl.noPrevious());
pages.unshift(firstPage);
return pages;
}

var lastPage = makePage(totalPages, lastText, false, paginationCtrl.noNext());
pages.push(lastPage);
var originalRender = paginationCtrl.render;
paginationCtrl.render = function() {
originalRender();
if (scope.page > 0 && scope.page <= scope.totalPages) {
scope.pages = getPages(scope.page, scope.totalPages);
}

return pages;
};
}
};
Expand All @@ -206,47 +188,27 @@ angular.module('ui.bootstrap.pagination', [])
align: true
})

.directive('pager', ['pagerConfig', function(config) {
.directive('pager', ['pagerConfig', function(pagerConfig) {
return {
restrict: 'EA',
scope: {
totalItems: '='
totalItems: '=',
previousText: '@',
nextText: '@'
},
require: ['pager', '?ngModel'],
controller: 'PaginationController',
templateUrl: 'template/pagination/pager.html',
replace: true,
link: function(scope, element, attrs, ctrls) {
var paginationCtrl = ctrls[0], ngModel = ctrls[1];
var paginationCtrl = ctrls[0], ngModelCtrl = ctrls[1];

if (!ngModel) {
if (!ngModelCtrl) {
return; // do nothing if no ng-model
}

// Setup configuration parameters
var previousText = paginationCtrl.getAttributeValue(attrs.previousText, config.previousText, true),
nextText = paginationCtrl.getAttributeValue(attrs.nextText, config.nextText, true),
align = paginationCtrl.getAttributeValue(attrs.align, config.align);

paginationCtrl.init(ngModel, config.itemsPerPage);

// Create page object used in template
function makePage(number, text, isDisabled, isPrevious, isNext) {
return {
number: number,
text: text,
disabled: isDisabled,
previous: ( align && isPrevious ),
next: ( align && isNext )
};
}

paginationCtrl.getPages = function(currentPage) {
return [
makePage(currentPage - 1, previousText, paginationCtrl.noPrevious(), true, false),
makePage(currentPage + 1, nextText, paginationCtrl.noNext(), false, true)
];
};
scope.align = angular.isDefined(attrs.align) ? scope.$parent.$eval(attrs.align) : pagerConfig.align;
paginationCtrl.init(ngModelCtrl, pagerConfig);
}
};
}]);
3 changes: 2 additions & 1 deletion template/pagination/pager.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<ul class="pager">
<li ng-repeat="page in pages track by $index" ng-class="{disabled: page.disabled, previous: page.previous, next: page.next}"><a href ng-click="selectPage(page.number)">{{page.text}}</a></li>
<li ng-class="{disabled: noPrevious(), previous: align}"><a href ng-click="selectPage(page - 1)">{{getText('previous')}}</a></li>
<li ng-class="{disabled: noNext(), next: align}"><a href ng-click="selectPage(page + 1)">{{getText('next')}}</a></li>
</ul>
6 changes: 5 additions & 1 deletion template/pagination/pagination.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<ul class="pagination">
<li ng-repeat="page in pages track by $index" ng-class="{active: page.active, disabled: page.disabled}"><a href ng-click="selectPage(page.number)">{{page.text}}</a></li>
<li ng-if="boundaryLinks" ng-class="{disabled: noPrevious()}"><a href ng-click="selectPage(1)">{{getText('first')}}</a></li>
<li ng-if="directionLinks" ng-class="{disabled: noPrevious()}"><a href ng-click="selectPage(page - 1)">{{getText('previous')}}</a></li>
<li ng-repeat="page in pages track by $index" ng-class="{active: page.active}"><a href ng-click="selectPage(page.number)">{{page.text}}</a></li>
<li ng-if="directionLinks" ng-class="{disabled: noNext()}"><a href ng-click="selectPage(page + 1)">{{getText('next')}}</a></li>
<li ng-if="boundaryLinks" ng-class="{disabled: noNext()}"><a href ng-click="selectPage(totalPages)">{{getText('last')}}</a></li>
</ul>