More articles

How To Paginate Through A Collection In Javascript

Written by
Filed under
Published on
Modified on

Pagination is one of those annoying features that aren't fun to implement in any language, but that is pretty much essential for a good UI. Nowadays you can download any one of dozens of JavaScript libraries that will take care of most aspects of pagination for you on the client side, but having more control of your own code is always a big plus.

If you are relatively new to JavaScript, then I recommend Web Design with HTML, CSS, JavaScript and jQuery as a good starting point.

The following is a quick implementation that covers the basics of what pagination is and how it functions. Feel free to modify it in any way that you wish. A few improvements could be to add numeric paging to it and to allow for multiple pagers per page, etc.

Tabular pagination

What is pagination? We have a collection of data in some format. We then specify a set number of elements that we want to display per page. We render our pagination controls, such as next and previous. And depending on which page we are on, we will cut a chunk of the 'data' out based on the current page and the number of elements per page, and we render the data. We then redraw our pager controls and we're good to go.

Define A Few Variables

Let's start by setting up the variables that we will need to store the paging data, such as the number of items per page and the current page we're on, and we'll have an Array to hold our data. We'll also create a subsection of our Array to store just the currently displayed elements.

// global JavaScript variables

var list = new Array(); var pageList = new Array(); var currentPage = 1; var numberPerPage = 10; var numberOfPages = 1; // calculates the total number of pages

The list variable will store the collection of data to be sorted. This can be anything from strings, integers to JavaScript objects. The currentPage variable will keep track of where we are in the pagination. numberPerPage dictates the amount of items to show per page. pageList plays a very important role in the script as it will keep track of the items to display on the current page only. We don't need to store it separately, but depending on your data it can make the process easier and for our example, it will make the process easier to follow. The numberOfPages is calculated on load and will tell us the total number of pages required to render in the collection. This is necessary if we're going to be doing numeric pagination.

Next up let's create some sample data to work with. An array of 200 integers should be enough to get an idea of the process.

1. Create A Test List (optional)

If you have data ready to go you can skip this step. Otherwise, run the function onLoad.


function makeList() {
    for (x = 0; x < 200; x++)
        list.push(x);
}

function load() {
    makeList();
}
    
window.addEventListener('load', load);

2. Calculate Number of Pages

We'll need to know the number of pages in our application so that we can handle enabling and disabling the pager buttons accordingly. For example, getting to the last page will automatically disable the next and last buttons, etc. We can add this functionality to our load function.

function load(){
    makeList();
    numberOfPages = getNumberOfPages();
}
function getNumberOfPages() {
    return Math.ceil(list.length / numberPerPage);
}

3. Create Paging Buttons

We'll be making a first-next-previous-last pager to navigate through the pages. After each page is loaded a check will occur to verify the state of all the buttons, such as disabling the next button when the last page is reached as mentioned previously.

The following HTML will render the pagination controls.

<body>
	<input type="button" id="first" onclick="firstPage()" value="first" />
	<input type="button" id="next" onclick="nextPage()" value="next" />
	<input type="button" id="previous" onclick="previousPage()" value="previous" />
	<input type="button" id="last" onclick="lastPage()" value="last" />
</body>

Each button control will call a different function. The only difference in each functions implementation is the value of the currentPage variable that gets set. After that we call loadList(), which is the function that will draw the elements onto the screen.

The nextPage function is implemented as follows:

function nextPage() {
    currentPage += 1;
    loadList();
}

While the previousPage function is as such:

function previousPage() {
    currentPage -= 1;
    loadList();
}

Here is the firstPage function

function firstPage() {
    currentPage = 1;
    loadList();
}

And last but not least, the lastPage function.

function lastPage() {
    currentPage = numberOfPages;
    loadList();
}

It's essentially the same function called each time with a change in a variable. For something this simple, inlining the script might be preferred.

4. LoadList()

Next up is splitting our data up into their appropriate page counterparts. First, we calculate the index of the first element and of the last element for that particular page. Next up we call the slice function of our Array and tell it where to start slicing from and where to end. The result will be an Array with just the elements that we're currently looking for. You start at the current page, minus one, plus the page offset. And the end is just that start number plus the offset again. The 2 new functions at the bottom drawList and check will render the sublist and then update the pager buttons respectively.

function loadList() {
    var begin = ((currentPage - 1) * numberPerPage);
    var end = begin + numberPerPage;

    pageList = list.slice(begin, end);
    drawList();    // draws out our data
    check();         // determines the states of the pagination buttons
}

5. Draw The List

The drawList function will spit out the values in the pageList Array variable.

function drawList() {
    document.getElementById("list").innerHTML = "";
    
    for (r = 0; r < pageList.length; r++) {
        document.getElementById("list").innerHTML += pageList[r] + "
"; } }

6. Update Button Statuses

So far we have an Array with the items to paginate through, and our control buttons that will determine which page we go to next. And we have our function that will set the elements for the current page that we are on. That's a fully working pagination module. But, we can do a bit better. After each new sublist is loaded we'll want to determine the state of the paging buttons (next, prev, first, last). For example, if we are on page 1, then our first and previous buttons should be disabled. We can run the following function after each new page list is generated.

function check() {
    document.getElementById("next").disabled = currentPage == numberOfPages ? true : false;
    document.getElementById("previous").disabled = currentPage == 1 ? true : false;
    document.getElementById("first").disabled = currentPage == 1 ? true : false;
    document.getElementById("last").disabled = currentPage == numberOfPages ? true : false;
}

7. Full Working Code

Here is the full working JS example for your copy/paste pleasure.

<script type="text/javascript">
    var list = new Array();
    var pageList = new Array();
    var currentPage = 1;
    var numberPerPage = 10;
    var numberOfPages = 0;

function makeList() {
    for (x = 0; x < 200; x++)
        list.push(x);

    numberOfPages = getNumberOfPages();
}
    
function getNumberOfPages() {
    return Math.ceil(list.length / numberPerPage);
}

function nextPage() {
    currentPage += 1;
    loadList();
}

function previousPage() {
    currentPage -= 1;
    loadList();
}

function firstPage() {
    currentPage = 1;
    loadList();
}

function lastPage() {
    currentPage = numberOfPages;
    loadList();
}

function loadList() {
    var begin = ((currentPage - 1) * numberPerPage);
    var end = begin + numberPerPage;

    pageList = list.slice(begin, end);
    drawList();
    check();
}
    
function drawList() {
    document.getElementById("list").innerHTML = "";
    for (r = 0; r < pageList.length; r++) {
        document.getElementById("list").innerHTML += pageList[r] + "<br/>";
    }
}

function check() {
    document.getElementById("next").disabled = currentPage == numberOfPages ? true : false;
    document.getElementById("previous").disabled = currentPage == 1 ? true : false;
    document.getElementById("first").disabled = currentPage == 1 ? true : false;
    document.getElementById("last").disabled = currentPage == numberOfPages ? true : false;
}

function load() {
    makeList();
    loadList();
}
    
window.onload = load;
</script>
<body>
    <div style="text-align:center;">
    <input type="button" id="first" onclick="firstPage()" value="first" />
    <input type="button" id="next" onclick="nextPage()" value="next" />
    <input type="button" id="previous" onclick="previousPage()" value="previous" />
    <input type="button" id="last" onclick="lastPage()" value="last" />

    <div id="list"></div>
    </div>
</body>

Update 1: I have updated the code to include numeric pagination, which you can find by clicking here.

Update 2: If you are rendering more complex HTML elements to your list, you can find out how to do that over in this article.

Land your next big coding job. Search through 1000's of job listings.

Discussion / Comments / Questions

S
Spenser
3/1/2016 7:09:59 AM
Great resource! I needed to create pagination based on a custom table layout because I am using rowSpan. There aren't really any tools that offer pagination for a table that implements rowSpan, so I was able to use this by just changing up the makeList() and drawList() functions. Appreciate this solution.
Walter G.
3/1/2016 10:58:37 PM
Thanks Spenser! Definitely glad it helped you out!
e
edellucien
10/5/2016 4:06:09 AM
Cheers! Thanks a lot, helped me to create the required pagination for my website. Working on it in order to add the display of numbered buttons to improve the display.
Walter G.
10/5/2016 6:53:02 AM
Well thank you. Very happy to hear it helped you out!
K
KJ
4/14/2019 4:22:11 PM
how to add link of my webpages to the list generated by this code? very useful,
P
Pete
10/8/2019 8:48:53 PM
Hey, this is a really interesting and straightforward solution - thanks for sharing. Any tips on how to break each page's array down into columns?
Walter G.
10/9/2019 1:20:47 PM
Many thanks for the kind words. Glad you found it useful. If you were looking to turn the data into a table-like format, you could add objects into the array, instead of scalar values. And you would need to update the drawList() function to render an HTML table instead of just values. Hope that helps!
P
Pete
10/9/2019 7:59:05 PM
Thanks!
l
lizzy
10/10/2019 5:41:07 AM
I found this useful, although I am very new to javascript and still a bit unstable, how can this help me for pagination of blog post rendered from an API. Thanks
Walter G.
10/10/2019 12:31:47 PM
Hey there! Definitely glad you found it useful. One way you can use it to render your own content, would be to store your blog data as a collection of objects and add those to the array. Most of the work would then go into the drawList() function, in which you would render your blog layout for each item. Hope that helps!
A
Andrew King
10/15/2019 10:01:05 AM
The site is still under development. I create each entry manually and can be individual in design. Is there a way I can give each entry a number to replace the 0-200 that exists in your coding. Could it be that each element could have its own div (ie class/value/id). Am I taking the wrong path or is there an obvious way I am missing. Any help will be gratefully received.
Walter G.
10/15/2019 10:29:36 AM
Hey there Andrew. Thanks for the question. For sure each element can be a more complex HTML segment. You would need to have whatever data you wish to render in a collection of Objects. And instead of setting the innerHTML, as I did above, you can create a new html element using document.createElement('div') for every object that you have. I will be updating this article with a more updated version soon that will cover that in depth!
?
???????
11/29/2019 7:59:30 AM
??????? ? ??????? ???, ??????? ???????!
D
Dmitriy
11/29/2019 8:01:05 AM
Nice and working code, thanks a lot!

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post comment