Skip to content

Commit

Permalink
Update to v0.5.0
Browse files Browse the repository at this point in the history
See release notes for details
  • Loading branch information
michaelbromley committed Dec 18, 2014
1 parent 9c2ae9e commit 4afd671
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 22 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "angularUtils-pagination",
"version": "0.4.0",
"version": "0.5.0",
"homepage": "https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination",
"authors": [
"Michael Bromley <michael@michaelbromley.co.uk>"
Expand Down
86 changes: 65 additions & 21 deletions dirPagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Config
*/
var moduleName = 'angularUtils.directives.dirPagination';
var DEFAULT_ID = '__default';

/**
* Module
Expand All @@ -40,15 +41,6 @@
priority: 5000, // This setting is used in conjunction with the later call to $compile() to prevent infinite recursion of compilation
compile: function dirPaginationCompileFn(tElement, tAttrs){

// Add ng-repeat to the dom element
if (tElement[0].hasAttribute('dir-paginate-start') || tElement[0].hasAttribute('data-dir-paginate-start')) {
// using multiElement mode (dir-paginate-start, dir-paginate-end)
tAttrs.$set('ngRepeatStart', tAttrs.dirPaginate);
tElement.eq(tElement.length - 1).attr('ng-repeat-end', true);
} else {
tAttrs.$set('ngRepeat', tAttrs.dirPaginate);
}

var expression = tAttrs.dirPaginate;
// regex taken directly from https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js#L211
var match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
Expand All @@ -60,10 +52,35 @@
var itemsPerPageFilterRemoved = match[2].replace(filterPattern, '');
var collectionGetter = $parse(itemsPerPageFilterRemoved);

var paginationId = tAttrs.paginationId || '__default';
paginationService.registerInstance(paginationId);
// If any value is specified for paginationId, we register the un-evaluated expression at this stage for the benefit of any
// dir-pagination-controls directives that may be looking for this ID.
var rawId = tAttrs.paginationId || DEFAULT_ID;
paginationService.registerInstance(rawId);

return function dirPaginationLinkFn(scope, element, attrs){

// Now that we have access to the `scope` we can interpolate any expression given in the paginationId attribute and
// potentially register a new ID if it evaluates to a different value than the rawId.
var paginationId = $parse(attrs.paginationId)(scope) || attrs.paginationId || DEFAULT_ID;
paginationService.registerInstance(paginationId);

var repeatExpression;
var idDefinedInFilter = !!expression.match(/(\|\s*itemsPerPage\s*:[^|]*:[^|]*)/);
if (paginationId !== DEFAULT_ID && !idDefinedInFilter) {
repeatExpression = expression.replace(/(\|\s*itemsPerPage\s*:[^|]*)/, "$1 : '" + paginationId + "'");
} else {
repeatExpression = expression;
}

// Add ng-repeat to the dom element
if (element[0].hasAttribute('dir-paginate-start') || element[0].hasAttribute('data-dir-paginate-start')) {
// using multiElement mode (dir-paginate-start, dir-paginate-end)
attrs.$set('ngRepeatStart', repeatExpression);
element.eq(element.length - 1).attr('ng-repeat-end', true);
} else {
attrs.$set('ngRepeat', repeatExpression);
}

var compiled = $compile(element, false, 5000); // we manually compile the element again, as we have now added ng-repeat. Priority less than 5000 prevents infinite recursion of compiling dirPaginate

var currentPageGetter;
Expand Down Expand Up @@ -183,27 +200,37 @@
},
scope: {
maxSize: '=?',
onPageChange: '&?'
onPageChange: '&?',
paginationId: '=?'
},
link: function(scope, element, attrs) {
link: function dirPaginationControlsLinkFn(scope, element, attrs) {

var paginationId;
paginationId = attrs.paginationId || '__default';
if (!scope.maxSize) { scope.maxSize = 9; }
scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true;
scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false;
// rawId is the un-interpolated value of the pagination-id attribute. This is only important when the corresponding dir-paginate directive has
// not yet been linked (e.g. if it is inside an ng-if block), and in that case it prevents this controls directive from assuming that there is
// no corresponding dir-paginate directive and wrongly throwing an exception.
var rawId = attrs.paginationId || DEFAULT_ID;
var paginationId = scope.paginationId || attrs.paginationId || DEFAULT_ID;

if (!paginationService.isRegistered(paginationId)) {
var idMessage = (paginationId !== '__default') ? ' (id: ' + paginationId + ') ' : ' ';
if (!paginationService.isRegistered(paginationId) && !paginationService.isRegistered(rawId)) {
var idMessage = (paginationId !== DEFAULT_ID) ? ' (id: ' + paginationId + ') ' : ' ';
throw 'pagination directive: the pagination controls' + idMessage + 'cannot be used without the corresponding pagination directive.';
}

if (!scope.maxSize) { scope.maxSize = 9; }
scope.directionLinks = angular.isDefined(attrs.directionLinks) ? scope.$parent.$eval(attrs.directionLinks) : true;
scope.boundaryLinks = angular.isDefined(attrs.boundaryLinks) ? scope.$parent.$eval(attrs.boundaryLinks) : false;

var paginationRange = Math.max(scope.maxSize, 5);
scope.pages = [];
scope.pagination = {
last: 1,
current: 1
};
scope.range = {
lower: 1,
upper: 1,
total: 1
};

scope.$watch(function() {
return (paginationService.getCollectionLength(paginationId) + 1) * paginationService.getItemsPerPage(paginationId);
Expand Down Expand Up @@ -239,6 +266,7 @@
if (isValidPageNumber(num)) {
scope.pages = generatePagesArray(num, paginationService.getCollectionLength(paginationId), paginationService.getItemsPerPage(paginationId), paginationRange);
scope.pagination.current = num;
updateRangeValues();

// if a callback has been set, then call it with the page number as an argument
if (scope.onPageChange) {
Expand All @@ -255,9 +283,25 @@
scope.pagination.last = scope.pages[scope.pages.length - 1];
if (scope.pagination.last < scope.pagination.current) {
scope.setCurrent(scope.pagination.last);
} else {
updateRangeValues();
}
}

/**
* This function updates the values (lower, upper, total) of the `scope.range` object, which can be used in the pagination
* template to display the current page range, e.g. "showing 21 - 40 of 144 results";
*/
function updateRangeValues() {
var currentPage = paginationService.getCurrentPage(paginationId),
itemsPerPage = paginationService.getItemsPerPage(paginationId),
totalItems = paginationService.getCollectionLength(paginationId);

scope.range.lower = (currentPage - 1) * itemsPerPage + 1;
scope.range.upper = Math.min(currentPage * itemsPerPage, totalItems);
scope.range.total = totalItems;
}

function isValidPageNumber(num) {
return (numberRegex.test(num) && (0 < num && num <= scope.pagination.last));
}
Expand All @@ -269,7 +313,7 @@

return function(collection, itemsPerPage, paginationId) {
if (typeof (paginationId) === 'undefined') {
paginationId = '__default';
paginationId = DEFAULT_ID;
}
if (!paginationService.isRegistered(paginationId)) {
throw 'pagination directive: the itemsPerPage id argument (id: ' + paginationId + ') does not match a registered pagination-id.';
Expand Down

0 comments on commit 4afd671

Please sign in to comment.