Home > Back-end >  Generating pagination button numbers and dots
Generating pagination button numbers and dots

Time:11-09

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;
  };
  • Related