Skip to content

Instantly share code, notes, and snippets.

@eokoneyo
Last active January 31, 2020 15:46
Show Gist options
  • Save eokoneyo/c5bc734bed2836f4ef64bfe35674f53a to your computer and use it in GitHub Desktop.
Save eokoneyo/c5bc734bed2836f4ef64bfe35674f53a to your computer and use it in GitHub Desktop.
'use strict';
/**
* @description dust helper for building pagination component.
* @example {@pager end=total_pages baseurl="/search" query=query /}
*/
let qs = require('query-string');
module.exports = (dust) => {
return (chunk, context, bodies, params) => {
//tapping these to get the actual value (since we passed variables) and casting as a number with '+'
let first = +dust.helpers.tap(params.start, chunk, context) || 1;
let last = +dust.helpers.tap(params.end, chunk, context);
//if the last param isn't set don't bother with the computations
if (!last || last < 2) { return chunk; };
let query = dust.helpers.tap(params.query, chunk, context);
let url = dust.helpers.tap(params.baseurl, chunk, context);
let limit = dust.helpers.tap(params.limit, chunk, context) || 5;
let page = parseInt(query.page) || 1;
let _query = Object.assign({}, query);
//remove the current page property from your cloned object so its not included in the returned url we are building;
delete _query.page;
//stringify the _query obj so we can use it in the url
let stringified = qs.stringify(_query);
url = (stringified) ? `${url}?${stringified}&page=%page%` : `${url}?page=%page%`;
//build our html - do whatever you need here - this is an example
let html = `<nav aria-label="Page navigation" style="text-align: center;">
<ul class="pagination">
<li ${(page === first) ? 'class="disabled"' : ''}>
<a ${ (page === first) ? '' : 'href="' + url.replace('%page%', first) + '"'} aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>`;
if ((last < limit) && (page <= limit)) {
for (let i = 1; i <= last; i++) {
if (i === page) {
//apply active class on active page
html += `<li class="active"><a href="${url.replace('%page%', i)}">${i}</a></li>`;
} else {
html += `<li><a href="${url.replace('%page%', i)}">${i}</a></li>`;
}
}
} else if (page <= limit) {
for (let i = 1; i <= limit; i++) {
if (i === page) {
//apply active class on active page
html += `<li class="active"><a href="${url.replace('%page%', i)}">${i}</a></li>`;
} else {
html += `<li><a href="${url.replace('%page%', i)}">${i}</a></li>`;
}
}
} else {
//we add and subtract 2 on either side of the current so our display limit remains 5
let leftSubtract = page - 2;
let rightSubtract = page + 2;
let count = 0;
//if number for right boundary is higher than our page total, reduce it till its lesser than the page total
while (rightSubtract > last) {
count++;
rightSubtract--;
}
//if the difference of the left boundary and right boundary is not equal to the set pagination limit alter its value to match expectation
if ((rightSubtract - leftSubtract) !== limit) {
leftSubtract = rightSubtract - limit;
}
for (let i = leftSubtract; i <= rightSubtract; i++) {
if (i === page) {
//apply active class on active page
html += `<li class="active"><a href="${url.replace('%page%', i)}">${i}</a></li>`;
} else {
html += `<li><a href="${url.replace('%page%', i)}">${i}</a></li>`;
}
}
};
html += `<li ${(page === last) ? 'class="disabled"' : ''}>
<a ${ (page === last) ? '' : 'href="' + url.replace('%page%', last) + '"'} aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</ul>
</nav>`;
//write this back to the template
return chunk.write(html);
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment