(function () { "use strict"; var name = 'adPagination'; angular.module('app.directive') .constant(name + 'Config', { maxSize: 10, boundaryLinks: true, directionLinks: true, firstText: '«', prevText: '‹', nextText: '›', lastText: '»', rotate: true }) .directive('adPagination', ['$parse', name + 'Config', function ($parse, config) { return { restrict: 'EA', scope: { /** @type {PaginationInfo} */ pagination: '=' + name }, templateUrl: 'directive/' + name + '/' + name + '.html', replace: true, link: function (scope, element, attributes) { var limit = angular.isDefined(attributes.limit) ? parseInt(attributes.limit) : config.maxSize, boundaryLinks = config.boundaryLinks, directionLinks = config.directionLinks, firstText = config.firstText, prevText = config.prevText, nextText = config.nextText, lastText = config.lastText, rotate = config.rotate; var onPaginationChange = $parse(attributes[name + 'Change']); var noPrev = function () { return scope.pagination.currentPageIndex === 0; }; var noNext = function () { return scope.pagination.currentPageIndex === scope.pagination.pageCount - 1; }; var isActive = function (index) { return scope.pagination.currentPageIndex === index; }; var render = function () { if (scope.pagination.currentPageIndex >= 0 && scope.pagination.currentPageIndex < scope.pagination.pageCount) { scope.pages = getPages(); } else { scope.pages = []; } }; var makePage = function (index, text, isActive, isDisabled) { return { index: index, text: text, active: isActive, disabled: isDisabled }; }; var getPages = function () { var pageIndex = scope.pagination.currentPageIndex; var pageCount = scope.pagination.pageCount; var pages = []; // Default page limits var startIdx = 0, endIdx = pageCount - 1; var isMaxSized = ( angular.isDefined(limit) && limit < pageCount ); // recompute if limit if (isMaxSized) { if (rotate) { // Current page is displayed in the middle of the visible ones startIdx = Math.max(pageIndex - Math.floor(limit / 2), 0); endIdx = startIdx + limit - 1; // Adjust if limit is exceeded if (endIdx >= pageCount) { endIdx = pageCount - 1; startIdx = endIdx - limit; } } else { // Visible pages are paginated with limit startIdx = ((Math.ceil(pageIndex / limit) - 1) * limit) + 1; // Adjust last page if limit is exceeded endIdx = Math.min(startIdx + limit - 1, pageCount); } } // Add page index links for (var index = startIdx; index <= endIdx; index++) { var page = makePage(index, index + 1, isActive(index), false); pages.push(page); } // Add links to move between page sets if (isMaxSized && !rotate) { if (startIdx > 0) { var previousPageSet = makePage(startIdx - 1, '...', false, false); pages.unshift(previousPageSet); } if (endIdx < pageCount - 2) { var nextPageSet = makePage(endIdx + 1, '...', false, false); pages.push(nextPageSet); } } // Add previous & next links if (directionLinks) { // prev page pages.unshift(makePage(pageIndex - 1, prevText, false, noPrev())); // next page pages.push(makePage(pageIndex + 1, nextText, false, noNext())); } // Add first & last links if (boundaryLinks) { // first page pages.unshift(makePage(0, firstText, false, noPrev())); // last page pages.push(makePage(pageCount - 1, lastText, false, noNext())); } return pages; }; scope.selectPage = function (index) { if (!isActive(index) && index >= 0 && index < scope.pagination.pageCount) { scope.pagination.currentPageIndex = index; onPaginationChange(scope.$parent, {index: index}); render(); } }; scope.$watch('pagination', function () { render(); }); } }; }]); })();