Nice Paging Steps
Bert's algorithm to get the page numbers for the pagination dropdown, ported from Java to JavaScript
by Torsten Walter
HTML
<label for="currentPageNumber">current page number (0 based)</label>
<input name="currentPageNumber" type="number" value="9">
<br>
<label for="numPages">number of pages</label>
<input name="numPages" type="number" value="20">
<br>
<button id="calculate">calculate</button>
<hr>
<h3>Result</h3>
<pre id="result">No result yet, click “calculate”</pre>
JavaScript
const NICE_PAGING_STEPS = [1000, 500, 200, 100, 50, 20, 10, 5];
function applyNiceStepsToFirstPages(pageNumbers) {
let firstPageNumber = pageNumbers[0] + 1;
let start = -1;
let step = 1;
for (let startCandidate = 3; startCandidate <= 5; ++startCandidate) {
const stepCandidate = NICE_PAGING_STEPS.find(candidate => {
let temp = pageNumbers[startCandidate + 1] - pageNumbers[startCandidate + 1] % candidate - 1;
let page1 = temp - (startCandidate - 1) * candidate;
return page1 > firstPageNumber && candidate >= step;
});
if (stepCandidate) {
start = startCandidate;
step = stepCandidate;
}
/*for (let stepCandidate of NICE_PAGING_STEPS) {
let temp = pageNumbers[startCandidate + 1] - pageNumbers[startCandidate + 1] % stepCandidate - 1;
let page1 = temp - (startCandidate - 1) * stepCandidate;
if (page1 > firstPageNumber && stepCandidate >= step) {
start = startCandidate;
step = stepCandidate;
break;
}
}*/
}
if (step > 1) {
pageNumbers[start] = pageNumbers[start + 1] - pageNumbers[start + 1] % step - 1;
for (let i = start - 1; i >= 1; --i) {
pageNumbers[i] = pageNumbers[i + 1] - step;
}
}
}
function applyNiceStepsToLastPages(pageNumbers) {
let lastPageNumber = pageNumbers[18];
let start = -1;
let step = 1;
for (let startCandidate = 15; startCandidate >= 13; --startCandidate) {
for (let stepCandidate of NICE_PAGING_STEPS) {
let temp = (pageNumbers[startCandidate - 1] + 2) - ((pageNumbers[startCandidate - 1] + 2) % stepCandidate) - 1 + stepCandidate;
let page17 = temp + (17 - startCandidate) * stepCandidate;
if (page17 < lastPageNumber && stepCandidate >= step) {
start = startCandidate;
step = stepCandidate;
...