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

Commit

Permalink
refactor(pagination): move boundary & directions to the template
Browse files Browse the repository at this point in the history
Closes #795
Closes #1770
  • Loading branch information
bekos committed Feb 13, 2014
1 parent c01d255 commit bce2505
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 91 deletions.
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>

0 comments on commit bce2505

Please sign in to comment.