Skip to content

Instantly share code, notes, and snippets.

@BideoWego
Created April 19, 2017 22:06
Show Gist options
  • Save BideoWego/a34e00007277fa03175fb0b1fc2624fd to your computer and use it in GitHub Desktop.
Save BideoWego/a34e00007277fa03175fb0b1fc2624fd to your computer and use it in GitHub Desktop.
Pagination algo in a project context
const _ = require('lodash');
function _createPages(current, max, delta) {
// Return nada if we got
// no pages
if (!max) {
return [];
}
// Find page display range
let left = current - delta;
let right = current + delta;
// Initialize page list
// with first page
let pages = [1];
// Find max between next page `2`
// and the beginning of the page
// range around the current page
// and set it to our start
let start = Math.max(2, left)
// Find the min between the right
// and the max pages
// and set it to our stop
let stop = Math.min(right, max);
// Begin iterating at the min
// and stop when we get to the right
// or when we get to max
for (let i = start; i <= stop; i++) {
// If the current i is in our display
// range push it onto the array
let isInRange = i >= left && i <= right;
if (isInRange) {
pages.push(i);
}
}
// If the last element in our array
// is not the last page number push it
if (pages[pages.length - 1] !== max) {
pages.push(max)
}
// Initialize last index
let last = 0;
// Adding ellipsis
// Start at 1 since last is set to 0
for (let i = 1; i < pages.length; i++) {
// Get previous page number
let a = pages[last];
// Get current page number
let b = pages[i];
// Get difference between them
let diff = b - a;
// If there is a difference
// larger than 1
if (diff > 1) {
// Close the gap if it is
// a single space
if (diff === 2) {
pages.splice(i, 0, b - 1);
} else {
// Else and ellipsis
pages.splice(i, 0, '...');
}
}
// Set last index
// to current
last = i;
}
// Return page list
return pages;
}
const PaginationHelper = {};
PaginationHelper.paginationFor = (options) => {
let limit = options.limit;
let page = +options.page || 0;
let count = options.count;
let offset = page * limit;
offset = offset < count ? offset : 0;
let total = Math.floor(count / limit);
let prev = page - 1;
let next = page + 1;
let pagination = {
limit: limit,
current: page,
url: options.url,
total: total,
offset: offset,
count: count
};
if (prev > 0) {
pagination.prev = prev;
}
if (next < total) {
pagination.next = next;
}
pagination.pages = _createPages(
page,
total,
options.delta || 4
);
return pagination;
};
module.exports = PaginationHelper;
const express = require('express');
const router = express.Router();
const h = require('./../helpers').registered;
const models = {
sequelize: require('./../models/sequelize')
};
const Product = models.sequelize.Product;
// ----------------------------------------
// Index
// ----------------------------------------
router.get(['/', '/products'], (req, res, next) => {
let pagination;
Product.count()
.then((result) => {
count = result;
pagination = h.paginationFor({
limit: 12,
page: +req.query.page,
count: count,
url: h.productsPath()
});
return Product.findAll({
limit: pagination.limit,
offset: pagination.offset
});
})
.then((result) => {
let products = result;
res.render('products/index', {
products,
pagination,
count
});
})
.catch(next);
});
module.exports = router;
{{#with options }}
<nav aria-label="Page navigation" class="text-center">
<ul class="pagination">
{{#if prev }}
<li>
<a href="{{ url }}?page={{ prev }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
{{/if }}
{{#each pages as |i| }}
<li
{{#if (eq i ../current) }}
class="active"
{{/if }}>
{{#if (eq i '...') }}
<a href="#" onclick="return false;">{{ i }}</a>
{{else }}
<a href="{{ url }}?page={{ i }}">{{ i }}</a>
{{/if}}
</li>
{{/each }}
{{#if next }}
<li>
<a href="{{ url }}?page={{ next }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
{{/if }}
</ul>
</nav>
{{/with }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment