Skip to content

Instantly share code, notes, and snippets.

@ajoslin
Created October 17, 2012 20:15
Show Gist options
  • Save ajoslin/3907871 to your computer and use it in GitHub Desktop.
Save ajoslin/3907871 to your computer and use it in GitHub Desktop.
/* An AngularJS directive to easily paginate any list of items */
/*
* The directive exposes a $pager (or other name set by ng-model) object to the view, with these properties
* $pager.items : array of current page's items
* $pager.index : current page index
* $pager.first : boolean, current page is first?
* $pager.last : boolean, current page is last?
* $pager.group : array of numbers representing current page group (eg [1,2,3,4,5])
* $pager.groupIndex : current group index
* $pager.groupFirst : boolean, current group is first group?
* $pager.groupLast : boolean, current group is last group?
* $pager.next() : go to next page, won't go past max page
* $pager.previous() : go to previous page, won't go below 0
* $pager.setPage(newPage) : set page, won't go outside bounds
*/
angular.module('ui', [])
.directive('paginator', ['$filter', '$parse', function ($filter, $parse) {
return {
restrict: 'EA',
link: function link($scope, $element, $attrs, $controller) {
var itemsPerPage = Math.max(+attrs.itemsPerPage, 1); //must be >0
pagesPerGroup = Math.max(+$attrs.pagesPerGroup, 1);
itemsPerGroup = itemsPerPage * pagesPerGroup,
itemsGet = $parse($attrs.items),
pager = {},
items = itemsGet($scope);
$parse($attrs.ngModel || '$pager').assign($scope, pager);
$scope.$watch(function() {
var parentValue = itemsGet($scope);
if (parentValue !== items) {
items = parentValue;
}
return parentValue;
});
var currentPage;
var currentGroup;
function currentPageItems() {
return items.splice(currentPage * itemsPerPage, currentPage * itemsPerPage + itemsPerPage);
}
function currentGroupArray() {
var group = [];
for (var i=1+currentPage*currentGroup, j=currentPage+pagesPerGroup; i<=j; i++) {
group.push(i);
}
return group;
}
function numPages() {
return Math.ceil(items.length / itemsPerPage);
}
function setPage(page) {
//Clamp new page between 0 and numPages()-1
currentPage = Math.max(0, Math.min(page, numPages() - 1));
currentGroup = Math.floor(currentPage / pagesPerGroup);
pager.items = currentPageItems();
pager.index = currentPage;
pager.first = currentPage == 0;
pager.last = currentPage == numPages() - 1;
pager.group = currentGroupArray();
pager.groupIndex = currentGroup;
pager.groupFirst = currentGroup == 0;
pager.groupLast = currentGroup == Math.floor((numPages()-1) / pagesPerGroup);
};
pager.next = function() {
setPage(currentPage + 1);
};
pager.previous = function() {
setPage(currentPage - 1);
};
pager.setPage = function(page) {
setPage(page);
};
setPage(0);
}
};
} ]);
function Ctrl($scope) {
var i;
$scope.updateProducts = function() {
var productsNum = Math.round(Math.random() * 100);
$scope.products = [];
for (i=0; i<productsNum; i++) {
$scope.products.push({
Name: "Product " + i,
Thumb: "http://placehold.it/120x100",
Price: (Math.random() * 1000).toFixed(2) + "€",
Description: "Very long description of Product " + i,
Detail: ""
});
}
};
$scope.updateProducts();
}​
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment