Pagination is one of those things that everyone hates implementing on their websites, and that we avoid doing until the data size calls for it. Or until the page is so long that the scroll wheel breaks off and the browser crashes. And for good reason. It's a somewhat tedious and needlessly complicated task normally. But a very much needed tedious and complicated task. The following script is designed to handle any and all client side pagination for HTML tables once and for all.

Add Pagination To Any Table In JavaScript

For a closer look at how the pagination logic works, feel free to check out my blog post right over here.

Feel free to use it and modify in any way that you wish as long as it helps you on your coding journey. All I ask, is that you throw some kind words my way if you do.

A quick example for your viewing pleasure.

2 rows per page
Index Name Address Phone
1 bob s. 123 fake st 333-333-3333
2 steve q. 123 fake st 333-333-3333
3 mary m s. 123 fake st 333-333-3333
4 nancy s. 123 fake st 333-333-3333

How it works

The entire process is very simple and obfuscates much of the complexity from the developer. Just add the script to your site and follow the following steps, and you'll have instant client side pagination, in under 100 lines of code.

1. Add the pagination class to each table that you want to add a pagination to.

2. Set the number of record elements per page, per table, in a dataset value, as such:

<table class="pagination" data-pagecount="3">

And that is it. Pagination complete. Here are a few examples of it in action for your paging pleasure again.

2 records per page
Index Name Address Phone
1 bob s. 123 fake st 333-333-3333
2 bob s. 123 fake st 333-333-3333
3 bob s. 123 fake st 333-333-3333
4 bob s. 123 fake st 333-333-3333

3 records per page
Index Name Address Phone
1 bob s. 123 fake st 333-333-3333
2 bob s. 123 fake st 333-333-3333
3 bob s. 123 fake st 333-333-3333
4 bob s. 123 fake st 333-333-3333

This is solely a client side implementation I must mention again and suited for small data sets. If you're dealing with thousands of records, then for sure you will need a server side implementation. Which I will cover in a future post.

In the meantime however, enjoy the script and use it as you will. Happy coding!

View full source

var perPage = 20;

function genTables() {
    var tables = document.querySelectorAll(".pagination");
    for (var i = 0; i < tables.length; i++) {
        perPage = parseInt(tables[i].dataset.pagecount);

// based on current page, only show the elements in that range
function loadTable(table) {
    var startIndex = 0;

    if (table.querySelector('th'))
        startIndex = 1;


    var start = (parseInt(table.dataset.currentpage) * table.dataset.pagecount) + startIndex;
    var end = start + parseInt(table.dataset.pagecount);
    var rows = table.rows;

    for (var x = startIndex; x < rows.length; x++) {
        if (x < start || x >= end)

function createTableMeta(table) {
    table.dataset.currentpage = "0";

function createFooters(table) {
    var hasHeader = false;
    if (table.querySelector('th'))
        hasHeader = true;

    var rows = table.rows.length;

    if (hasHeader)
        rows = rows - 1;

    var numPages = rows / perPage;
    var pager = document.createElement("div");

    // add an extra page, if we're 
    if (numPages % 1 > 0)
        numPages = Math.floor(numPages) + 1;

    pager.className = "pager";
    for (var i = 0; i < numPages ; i++) {
        var page = document.createElement("div");
        page.innerHTML = i + 1;
        page.className = "pager-item";
        page.dataset.index = i;

        if (i == 0)

        page.addEventListener('click', function() {
            var parent = this.parentNode;
            var items = parent.querySelectorAll(".pager-item");
            for (var x = 0; x < items.length; x++) {
            table.dataset.currentpage = this.dataset.index;

    // insert page at the top of the table
    table.parentNode.insertBefore(pager, table);

window.addEventListener('load', function() {

Walter G. is a software engineer, startup co-founder, former CTO of several tech companies and currently teaches programming for a coding bootcamp. He has been blogging for the past 5 years and is an avid BMX rider, bio-hacker and performance enthusiast.
If you read this far, then I hope you enjoyed this post and found it useful! Consider adding to my daily coffee funds to continue to provide better and more helpful articles in the future!
Maybe later

Add a comment

Send me your weekly newsletter filled with awesome ideas
Post comment