Logic of building a pagination UI component — a thought process

Jithil Jishad
4 min readApr 12, 2021

Recently I came across a need of figuring out logic for building a pagination component for a website. It was built in ASP.NET Core and had restrictions on using any external third party libraries for just the pagination. So I decided to build a pagination logic. Of course, I googled a bit to see if I can find something that can reduce my effort, but nothing useful came up. The thought process behind building my pagination component is the story I would like to share.

Beginning

First consideration, of course, was what should the pagination look like and how it should function.

  1. Display all pages available ::- bad UI/UX if number of pages are more.
  2. Display couple of pages from beginning and end, fill the gap with 3 dots ::- Difficult to indicate current position or navigation to adjacent.
  3. In option 2 above, add current and two adjacent pages in the middle (surrounded by dots as before) ::- Too complicated to build with not much worthy advantage for the user.
  4. Display maximum of 7 pages always with current page in the center whenever possible ::- Easier to build, compact, and size is controlled.

All approaches comes with next and previous buttons on the both ends, except while on the fist and the last pages.

From the above possibilities, my obvious choice was option 4. It would look like the image below:

On page 6 (out of 12)
On page 1 (out of 12)
On page 12 (out of 12)
On page 2 (out of 3)

Information required

Now that the design is ready, we will need some information to build the component. The basic necessary details required are listed below:

  • Total pages
  • Current page
  • Maximum number of pages to be displayed at a time

Now with this information, we need to get a list of pages to be rendered.

Logic of getting list of pages

In the above list of required information, current page will be obtained from the UI or request, and the maximum number of pages to display (will refer as maxPages) is a constant.

But we need to calculate the total number of pages. Logic for that is:

int totalPages = (int)Math.Ceiling((itemList.Count/(double)Constants.PageSize));

Once these information are ready, all we need is a list of page numbers to be displayed. For that I went through multiple approaches:

  1. Fixed number of pages (say, 3) on both sides of current page.

If I’m on page 6, then:

startPage = currentPage - 3;
endPage = currentPage + 3;

Seems pretty straightforward! But the problem comes when I don’t have 3 more pages to left or right of current page. For example on page 2, startPage will be -1 ! This is not possible. If current page is last page, then endPage will be last+3 which will be greater than total pages.

2. Use Max and Min to limit overflow.

That will look like:

startPage = Math.Max(1, currentPage - 3);
endPage = Math.Min(currentPage + 3, totalPages);

This will make sure no overflow happens. Great!

It will definitely take care of the lower limit. But what happens with the upper limit? Take an instance where you have totalPages=7, currentPage=2 and pageSize=7; By the above logic, startPage will be 1 and endPage will be 5. So we will be displaying only 5 pages when we are supposed to display maxPages=7 by design!

3. Start from middle and proceed towards both ends.

Now that we have seen a simple calculation is not sufficient to cover all use-cases, I thought of applying the same idea behind A* algorithm which I had studied once.

We will start from the current page and move towards both ends one step at a time. And thus we can obtain both maximum and sufficient number of pages to cover all the use-cases. The code will be as follows:

// Set pages obtained so far, start with 1 since we have currentPage
int pagesCount = 1;
// Maintain a copy of pagesCount.
// Used to detect whether any new pages were added in the iteration
int newPagesCount = 1;
// Set beginning and end as currentPage
int start = CurrentPage, end = CurrentPage;
// Continue iteration till enough pages are obtained
while(pagesCount<maxPages)
{
if (end + 1 <= TotalPages)
{
// Ok to take one more page towards end
end++;
newPagesCount++;
}
if(start - 1 > 0)
{
//Ok to take one more page towards start
start--;
newPagesCount++;
}
/*
Break loop if no additional pages were
obtained in this iteration
We have obtained maximum number of possible pages
*/
if (newPagesCount == pagesCount)
break;
else
pagesCount = newPagesCount;
}

Now we have a valid logic that will give us a start page number and an end page number for the current page in the list.

In C#, we can obtain the array of page numbers as:

int[] pages = Enumerable.Range(start, pagesCount).ToArray();

Put the above logic in a function and one can easily build a pagination with all the details we have obtained through this thought process.

This logic is for a specific design of pagination. A different design will need slight modification in the core logic. However the thought process will remain more or less the same.

Thanks for reading. Happy coding.

--

--

Jithil Jishad

Full-stack developer | Design Thinking | .NET Tech Stack