Skip to content

Instantly share code, notes, and snippets.

@john-yuan
Last active January 6, 2019 08:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save john-yuan/11a05426963ed28f9bc43bb2465be3e8 to your computer and use it in GitHub Desktop.
Save john-yuan/11a05426963ed28f9bc43bb2465be3e8 to your computer and use it in GitHub Desktop.
A function to generate the page number list for page links.
/**
* This function is used to generate the page list like below:
*
* ```
* [1] 2 3 4 5 6 » 20
* 1 « 6 7 [8] 9 10 » 20
* 1 « 15 16 17 18 19 [20]
* ```
*
* Note:
*
* In the returned page number array:
*
* 1. The special value `-1` represents a more page **before** the current one.
* 2. The special value `-2` represents a more page **after** the current one.
*
* This function just returns the page number array (consist of numbers). You
* can use the returned array to render the page list DOM or something you need.
* See the function demoRender(current: number, pages: number[]) below.
*
* @see {@link https://gist.github.com/john-yuan/11a05426963ed28f9bc43bb2465be3e8}
*
* @author John Yuan <https://github.com/john-yuan>
* @param {number} current - The current page number
* @param {number} max - The max page number
* @returns {number[]} - The page number array
*/
var pagination = function (current, max) {
'use strict';
var PREV_MORE = -1;
var NEXT_MORE = -2;
var pages = [];
var prev = current - 1;
var next = current + 1;
// if the max is less than 11, there is no `more` button needed
if (max <= 10) {
next = 1;
while (next <= max) {
pages.push(next);
next += 1;
}
} else {
// make sure we have 2 pages (if available) before the current page
if (prev >= 1) {
pages.unshift(prev);
prev -= 1;
if (prev >= 1) {
pages.unshift(prev);
prev -= 1;
if (prev === 1) {
pages.unshift(1);
} else if (prev === 2) {
pages.unshift(2);
pages.unshift(1);
} else if (prev > 2) {
pages.unshift(PREV_MORE);
pages.unshift(1);
}
}
}
pages.push(current);
// make sure that we have at least 6 pages (if available) in the first
if (pages[1] !== PREV_MORE && pages.length < 4) {
while (pages.length < 4 && next <= max) {
pages.push(next);
next += 1;
}
}
// make sure that we have 2 pages (if available) after the current page
if (next <= max) {
pages.push(next);
next += 1;
if (next <= max) {
pages.push(next);
next += 1;
if (next === max) {
pages.push(max);
} else if (next === (max - 1)) {
pages.push(max - 1);
pages.push(max);
} else if (next < (max - 1)) {
pages.push(NEXT_MORE);
pages.push(max);
}
}
}
// make sure that we have at least 6 pages (if available) in the end
if (pages[1] === PREV_MORE && pages[pages.length - 2] !== NEXT_MORE) {
prev = pages[2] - 1;
pages.shift(); // remove first page
pages.shift(); // rmeove PREV_MORE
while (pages.length < 6 && prev >= 1) {
pages.unshift(prev);
prev -= 1;
}
// add first page and PREV_MORE back
if (prev === 1) {
pages.unshift(1);
} else if (prev === 2) {
pages.unshift(2);
pages.unshift(1);
} else if (prev > 2) {
pages.unshift(PREV_MORE);
pages.unshift(1);
}
}
}
return pages;
};
//-------------------------------------TEST-------------------------------------
/**
* A demo render function to render the page list generated by pagination
*
* @param {number} current - The current page number
* @param {number[]} pages - The page number array
* @returns {string} - The rendered page list
*/
var demoRender = function (current, pages) {
var rendered = [];
pages.forEach(function (pageNo) {
if (pageNo === current) {
rendered.push('[' + pageNo + ']');
} else if (pageNo === -1) {
rendered.push('«')
} else if (pageNo === -2) {
rendered.push('»')
} else {
rendered.push(pageNo);
}
});
return rendered.join(' ');
};
/**
* This function is used to test the pagination function.
*
* @param {number} max - The max page number
*/
var testPagination = function (max) {
for (var i = 1; i <= max; i += 1) {
var pageList = demoRender(i, pagination(i, max));
console.log(pageList);
}
};
testPagination(20);
/*******************************************************************************
The output of testPagination(20):
[1] 2 3 4 5 6 » 20
1 [2] 3 4 5 6 » 20
1 2 [3] 4 5 6 » 20
1 2 3 [4] 5 6 » 20
1 2 3 4 [5] 6 7 » 20
1 « 4 5 [6] 7 8 » 20
1 « 5 6 [7] 8 9 » 20
1 « 6 7 [8] 9 10 » 20
1 « 7 8 [9] 10 11 » 20
1 « 8 9 [10] 11 12 » 20
1 « 9 10 [11] 12 13 » 20
1 « 10 11 [12] 13 14 » 20
1 « 11 12 [13] 14 15 » 20
1 « 12 13 [14] 15 16 » 20
1 « 13 14 [15] 16 17 » 20
1 « 14 15 [16] 17 18 19 20
1 « 15 16 [17] 18 19 20
1 « 15 16 17 [18] 19 20
1 « 15 16 17 18 [19] 20
1 « 15 16 17 18 19 [20]
*******************************************************************************/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment