I am trying to generated pagination button labels based on a few rules, and can't quite wrap my head around this.
I have 2 inputs, activePage
, which is the number of the current page and pageCount
which is the total number of pages. Depending on these I should be generating the following outputs:
activePage |
pageCount |
expected output |
---|---|---|
1 | 2 | ['<','1','2','>'] |
2 | 2 | ['<','1','2','>'] |
1 | 3 | ['<','1','2','3','>'] |
2 | 3 | ['<','1','2','3','>'] |
3 | 3 | ['<','1','2','3','>'] |
1 | 4 | ['<','1','2','3','4','>'] |
2 | 4 | ['<','1','2','3','4','>'] |
3 | 4 | ['<','1','2','3','4','>'] |
4 | 4 | ['<','1','2','3','4','>'] |
1 | 5 | ['<','1','2','3','...','5','>'] |
2 | 5 | ['<','1','2','3','...','5','>'] |
3 | 5 | ['<','1','2','3','4','5','>'] |
4 | 5 | ['<','1','...','3','4','5','>'] |
5 | 5 | ['<','1','...','3','4','5','>'] |
1 | 6 | ['<','1','2','3','...','6','>'] |
2 | 6 | ['<','1','2','3','4', '...', '6','>'] |
3 | 6 | ['<','1','2','3','4', '...', '6','>'] |
4 | 6 | ['<','1','...','3','4', '5','6','>'] |
5 | 6 | ['<','1','...','4', '5','6','>'] |
6 | 6 | ['<','1','...','4', '5','6','>'] |
4 | 7 | ['<','1','...','3','4','5','...','7','>'] |
The last pattern (4, 7) then repeats indefinitely, for example for 100 pages:
activePage: 33, totalPages: 100
: ['<', '1', '...' '32', '33', '34', '...', '100']
I am stumped just trying to write down the mathematical rule behind this. Any help is appreciated.
What I ended up was this bunch of if statements, and then got stuck trying to write down the generalisation for when the page count is more than 6.
const getPaginationButtons = (activePage: number, pageCount: number): string[] => {
if(pageCount > 6) {
// ... ?
}
if (pageCount === 6) {
if(activePage === 1) {
return ['1', '2', '3', '...', '6'];
}
// ... ?
if(activePage === 6) {
return ['1', '...', '4', '5', '6'];
}
}
if (pageCount === 5) {
const pages = [...new Array(pageCount)].map((_, index) =>
(index 1).toString()
);
if (activePage === 3) {
return pages;
}
if (activePage < 3) {
return pages.map((page) => (page === '4' ? '...' : page));
}
if (activePage > 3) {
return pages.map((page) => (page === '2' ? '...' : page));
}
return pages;
}
if (pageCount <= 4) {
const pages = [...new Array(pageCount)].map((_, index) =>
(index 1).toString()
);
return pages;
}
return [];
};
CodePudding user response:
Managed to get the test cases passing with the following code, but I still believe there might be a better way to code this:
const getPaginationButtons = (): string[] => {
if (pageCount <= 4) {
const pages = [...new Array(pageCount)].map((_, index) =>
(index 1).toString()
);
return pages;
}
const pages = ['1'];
if (activePage >= 4) {
pages.push('...');
}
if (activePage 1 > pageCount) {
pages.push((activePage - 2).toString());
}
if (activePage - 1 > 1) {
pages.push((activePage - 1).toString());
}
if (activePage !== 1) {
pages.push(activePage.toString());
}
if (activePage 1 <= pageCount) {
pages.push((activePage 1).toString());
}
if (activePage - 1 <= 0) {
pages.push((activePage 2).toString());
}
if (activePage 2 < pageCount) {
pages.push('...');
}
if (activePage 1 < pageCount) {
pages.push(pageCount.toString());
}
return pages;
};