AngularJS paginator directive
An AngularJS directive to easily paginate any list of items
The directive exposes this methods to the view:
* paginatedItems()
* pagesInGroup()
* hasPrevGroup()
* gotoPrevGroup()
* hasNextGroup()
* gotoNextGroup()
* hasPrevPage()
* gotoPrevPage()
* hasNextPage()
* gotoNextPage()
* gotoPage()
* itemsCount()
* firstItemNumber()
* lastItemNumber()
HTML
<div ng-app="ui" ng-controller="Ctrl" class="container">
<button ng-click="updateProducts()">Regenerate Products List</button>
<paginator
items="products"
items-per-page="9"
pages-per-group="2">
<div class="navigation">
<div class="items-count">{{firstItemNumber()}} - {{lastItemNumber()}} of {{itemsCount()}} items</div>
<div class="pages clearfix" ng-show="itemsCount() > itemsPerPage">
<button ng-disabled="!hasPrevPage()" ng-click="gotoPrevPage()">< Prev</button>
<ul clearfix>
<li ng-show="hasPrevGroup()" ng-click="gotoPrevGroup()">
...
</li>
<li ng-repeat="page in pagesInGroup()" ng-click="gotoPage(page.index)" ng-class="{active: page.active}">
{{page.index}}
</li>
<li ng-show="hasNextGroup()" ng-click="gotoNextGroup()">
...
</li>
</ul>
<button ng-disabled="!hasNextPage()" ng-click="gotoNextPage()">Next ></button>
</div>
<div class="sorter">
Sort by:
<select ng-model="sorting">
<option value="-Price">Price descending</option>
<option value="Price">Price ascending</option>
<option value="Name">Name A-Z</option>
<option value="-Name">Name Z-A</option>
</select>
</div>
</div>
<div class="items clearfix">
<div ng-repeat="item in paginatedItems()" class="item">
<div class="image">
<img ng-src="{{item.Thumb}}" alt="{{item.Name}}" />
</div>
<div class="name">
<a ng-href="{{item.Detail}}"...
CSS
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
.container {
padding: 10px;
}
.navigation {
margin-bottom: 10px;
}
.navigation .pages > * {
float: left;
}
.navigation .pages ul li {
float: left;
padding: 0 5px;
cursor: pointer;
}
.navigation .pages ul li.active {
font-weight: bold;
}
.items {
border-left: 1px solid black;
border-top: 1px solid black;
max-width: 423px;
}
.items .item {
float: left;
border-bottom: 1px solid black;
border-right: 1px solid black;
padding: 10px;
width: 120px;
}
.item .price {
font-weight: bold;
}
JavaScript
/* An AngularJS directive to easily paginate any list of items */
/*
* The directive exposes this methods to the view:
* paginatedItems()
* pagesInGroup()
* hasPrevGroup()
* gotoPrevGroup()
* hasNextGroup()
* gotoNextGroup()
* hasPrevPage()
* gotoPrevPage()
* hasNextPage()
* gotoNextPage()
* gotoPage()
* itemsCount()
* firstItemNumber()
* lastItemNumber()
*/
angular.module('ui', [])
.directive('paginator', ['$filter', '$parse',
function ($filter, $parse) {
return {
restrict: 'EA',
scope: true,
link: function link($scope, $element, $attrs, $controller) {
var itemsPerPage = $attrs.itemsPerPage * 1, // cast to number
pagesPerGroup = $attrs.pagesPerGroup * 1, // cast to number
itemsPerGroup = itemsPerPage * pagesPerGroup,
parentScope = $scope.$parent || $scope,
itemsGet = $parse($attrs.items);
$scope.items = itemsGet(parentScope);
$scope.$watch(function() {
var parentValue = itemsGet(parentScope);
if (parentValue !== $scope.items) {
$scope.items = parentValue;
}
return parentValue;
});
$scope.itemsPerPage = itemsPerPage;
var groups = [];
var currentGroup = 0;
var currentPage = 0;
$scope.sorting = 'Price';
function numItemsPreviousGroups() {
return itemsPerPage * pagesPerGroup * currentGroup;
}
function numItemsPreviousPages() {
return itemsPerPage * currentPage;
}
function firstItemCurrentPage() {
return angular.isDefined($scope.items) &&...