AngularJS paginator directive with service
HTML
<div ng-app="ui" ng-controller="Ctrl">
<button ng-click="updateProducts()">Regenerate Products List</button>
<div class="navigation">
<div class="items-count">{{products.firstItemNumber}} - {{products.lastItemNumber}} of {{products.totalItemCount}} items</div>
<div class="pages clearfix" ng-show="products.totalItemCount > products.itemsPerPage">
<button ng-disabled="products.first" ng-click="products.prev()">< Prev</button>
<ul clearfix>
<li ng-show="products.firstPageInRange != 1" ng-click="products.setPage(products.firstPageInRange - 1)">
... {{products.firstPageInRange}}
</li>
<li ng-repeat="page in products.pagesInRange" ng-click="products.setPage(page)" ng-class="{active: page == products.current}">
{{page}}
</li>
<li ng-show="products.lastPageInRange != products.pageCount" ng-click="products.setPage(products.lastPageInRange + 1)">
...{{products.lastPageInRange}}
</li>
</ul>
<button ng-disabled="products.last" ng-click="products.next()">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 products.items" class="item">
<div class="image">
<img ng-src="{{item.Thumb}}" alt="{{item.Name}}" />
</div>
<div class="name">
<a ng-href="{{item.Detail}}" target="_blank">{{item.Name}}</a>
</div>
<div...
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
/**
* uiPaginate implementation using a service
* The service is a function that accepts two parameters and returns a paginator
* object that exposes methods useful to render the view
*
* @param items {Array} the array of objects to be paginated
*
* @param options {Object} options to configure the service behaviour; accepted
* options are:
* - itemsPerPage {Number}: the number of items to show in every page
* - currentPage {Number}: the 1-based number of the first page to load
* - scrollingStyle {'all' | 'jumping' | 'sliding'}: the name of the
* algorithm to use to calculate the "pagesInRange" array (try them to
* see the differences)
* - pagesInRangeSize {Number}: the size of the "pagesInRange" array (just
* used by 'jumping' and 'sliding' algorithms)
*
* @returns {Object} a paginator that exposes these methods and properties:
* - items {Array}: the list of items in the current page
* - firstItemNumber {Number}: the absolute number of the first element
* in the current page
* - lastItemNumber {Number}: the absolute number of the last element
* in the current page
* - current {Number}: the 1-based number of the current page
* - first {Boolean}: true if the current page is the first page
* - last {Boolean}: true if the current page is the last page
* - pagesInRange {Array<Number>}: an array of page numbers which size
* and behaviour is determined by the 'pagesInRangeSize' and
* 'scrollingStyle' parameters
* - firstPageInRange {Number}: the number of the first page inside
* 'pagesInRange' parameter
* - lastPageInRange {Number}: the number of the last page inside
* 'pagesInRange' parameter
* - pageCount {Number}: the total number of pages
* - totalItemCount {Number}: the total number of items that were
* ...