Dynamic Pagination Rendering with pure JavaScript 🚀

Murat Dogan
Nov 5 · 4 min read

I have shared my experiences with creating sortable dynamic data tables. Now, I want to share another experimental story about dynamic pagination rendering.

Credit: Unsplash @markusspiske

I had to build a pagination module in a project. I examined lots of pagination libraries but these were so over-engineered compared to the product team’s requirements. I decided to build it on my own to make it simpler and easier to implement. Indeed, this widget implemented lots of different projects all around the production environment which has more than 50 million users per month and It works like a charm 🚀

Let me list the requirements we got from the product team:

  • We have a dynamic amount of elements
  • We want to show them dynamically per widget. e.g, while one widget is listing 10 of the elements per page another widget, may list 15 of the elements.
  • If it’s at the first or the latest page the arrow navigation buttons should be disabled, If the user clicks the active page it shouldn’t trigger anything, as well.
  • If we have more than 4 pages after the calculation regarding specs described below we need to show the latest page and show a button with three points. Here is the preview:

It has to look like this, at the end of the pagination:

Let’s look at the working demo, first:

It’s enough to give so much information. Let’s get our hands dirty:

First thing first, my little component should have a state which affects the rendering of it.

const pagingOptions = {
totalCount: 40,// Total content count
itemPerPage : 5, // How many items will be showed per page
initialPage: 1, // Initial Page (We can set this parameter by detecting current page from query string)
get totalPage () { // Calculating total page count
return Math.ceil(this.totalCount / this.itemPerPage) // I'm using Math.ceil for ceiling
},
location: ".paging", // It's the selector to render pagination component
url : "/api/contents/?id=5a5e47ec7152d929bc6d4280&p=" // The url address which will be requested after each page changed.
}

It was a .net framework web application that’s why I can init my function inside the razor.

paging.init(pagingOptions);

I love to stick with Single Responsibility principle while coding so I want to list my functions before digging into the details:

It’s also possible to merge handleNextClick and handlePrevClick functions but as I mentioned before this is just a POC. There may be so many points to improve inside the codebase. Please feel free to recommend better ways.

Let’s dig into the details. I’m passing down the current state using the init function. This is the function triggered each time when the page changed so I do request content part within this function

I want to mention one important method before I tell you about the createPaging method createButton. This method takes some parameters and helps me build each button regarding these parameters:

And finally one big, “dirty” method createPaging. I call it dirty just because it has so many conditions. I examined lots of pagination libraries and as far as I see, almost all of them have this kind of conditions. I do not want to show whole code here not to make you confused so I named the variables clearly to your debug.

Thanks for your time reading until this line. Please feel free to share your thoughts about the codebase. There is always a better way to improve.

Murat

JavaScript in Plain English

Learn the web's most important programming language.

Murat Dogan

Written by

Front End Architect@ Demirören Holding https://www.linkedin.com/in/muratdogan17/

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade