(function() { "use strict"; angular.module('shared') .component('pager', { bindings: { onPageChanged: '&', items: '@', itemsPerPage: '@?', onPageScrollTo: '@?', onPageFocusOn: '@?', pageSizesOption: '@?', noResetOnChange: '= MIN_ITEMS_PER_PAGE) { memo.push(size); } else { console.assert(false, 'Unsupported value "' + size + '" in page sizes') } } return memo; }, []).sort(function (first, second) { return first - second; }); if (all) { sizes.push(ALL); } if (sizes.length > 1) { ctrl.pageSizes = sizes; } } } function initItemsPerPage() { var attrItemsPerPage = ctrl.itemsPerPage && parseInt(ctrl.itemsPerPage, 10); ctrl.pageSize = (attrItemsPerPage >= MIN_ITEMS_PER_PAGE) ? attrItemsPerPage : (ctrl.pageSizes ? ctrl.pageSizes[0] : DEFAULT_ITEMS_PER_PAGE); } } function paginate(newCollection) { if (!Array.isArray(newCollection)) { return; } var destinationPage = 1; if (ctrl.noResetOnChange) { destinationPage = ctrl.currentPage == null ? 1: ctrl.currentPage; } collection = newCollection; ctrl.numPages = ctrl.pageSize === ALL ? 1 : Math.ceil(collection.length / ctrl.pageSize); setPage(destinationPage); } function isValidPage(page) { return (page >= 1 && page <= ctrl.numPages) || (page == 1 && !collection.length); } //Stronger than gotoPage, which may do nothing if same page function setPage(page) { if (!isValidPage(page)) { throw new RangeError('Invalid page value'); } var first = ctrl.currentPage === undefined; ctrl.currentPage = page; var offset = page - 1; ctrl.navigablePages = getNavigablePages(); ctrl.onPageChanged({page: getPage(offset), status: getStatus()}); if (!first) { checkScrollTo(); checkFocusOn(); } } function getPage(offset) { return ctrl.pageSize === ALL ? collection : collection.slice(offset * ctrl.pageSize, (offset + 1) * ctrl.pageSize); } function getStatus() { return { isShown: ctrl.showPager(), itemsPerPage: ctrl.pageSize, currentPage: ctrl.currentPage, numPages: ctrl.numPages, } } function getNavigablePages() { if (ctrl.numPages <= MAX_NAVIGABLE_PAGES + 2) { return _.range(2, ctrl.numPages); } if (ctrl.currentPage <= ADJACENT_NAVIGABLE_PAGES + 2) { return _.range(2, MAX_NAVIGABLE_PAGES + 2); } if (ctrl.currentPage >= ctrl.numPages - ADJACENT_NAVIGABLE_PAGES - 1) { return _.range(ctrl.numPages - MAX_NAVIGABLE_PAGES, ctrl.numPages); } return _.range(ctrl.currentPage - ADJACENT_NAVIGABLE_PAGES, ctrl.currentPage + ADJACENT_NAVIGABLE_PAGES + 1); } function gotoPage(page) { if (!isValidPage(page)) { throw new RangeError('Invalid page value'); } if (page != ctrl.currentPage) { setPage(page); } } function showPager() { return ctrl.numPages > 1; } function requestPage(page) { if (isValidPage(page)) { gotoPage(page); } else if (page < 1) { gotoPage(1); } else { gotoPage(ctrl.numPages); } } function goRelativePages(offset) { requestPage(ctrl.currentPage + offset); } function goRelativeBlocks(offset) { requestPage(ctrl.currentPage + offset * MAX_NAVIGABLE_PAGES); } function showLeftEllipsis() { return ctrl.navigablePages[0] > 2; } function showRightEllipsis() { return ctrl.navigablePages.slice(-1)[0] < ctrl.numPages - 1; } function showStatistics() { return showRightEllipsis(); } function isCurrentPage(page) { return ctrl.currentPage == page; } function checkScrollTo() { if (ctrl.onPageScrollTo) { scrollService.scrollToSelector(ctrl.onPageScrollTo, 500) } } function checkFocusOn() { if (ctrl.onPageFocusOn) { $timeout(doFocusOn); } } function doFocusOn() { var target = angular.element(ctrl.onPageFocusOn); var targetFocusable = target.filter(':focusable'); if (targetFocusable.length === 0) { targetFocusable = target.find(':focusable').first(); } targetFocusable.focus() } function showPageSizes() { return !!ctrl.pageSizes && collection.length > ctrl.pageSizes[0] } function isCurrentPageSize(size) { return ctrl.pageSize === size; } function goPageSize(size) { ctrl.pageSize = size; paginate(collection) } }]) })();