Thursday, April 21, 2011

Ajax Html Table Pagination

I have modified that code a bit, which will help providing google style paging e.g. 1 to 10, 20 to 30. Below is the modified code in pagination.js


Features it will provide:
1. google style pagination.
2. number of records.
3. can be used with multiple tables in one page.
4. will hide next and previous when not required.
5. First and last page links.


Steps:
1. add pagination.js in your jsp.
2. two extra css. "regularDataBlue" which is used to show dots... and "regularData" to show number of records.


pagination.js


function Pager(tableName, itemsPerPage, pagerName, positionId) {
    this.tableName = tableName;
    this.itemsPerPage = itemsPerPage;
    this.pagerName = pagerName;
    this.positionId = positionId;
    this.currentPage = 1;
    this.pages = 0;
    this.inited = false;
    this.numbers = new Array(10);


    this.showRecords = function (from, to) {
        var table = document.getElementById(tableName);
        var rows = table.rows;
        // i starts from 1 to skip table header row
        for (var i = 1; i < rows.length; i++) {
            if (i < from || i > to) rows[i].style.display = 'none';
            else rows[i].style.display = '';
        }
    }


    this.showPage = function (pageNumber) {
        if (!this.inited) {
            alert("not inited");
            return;
        }




        if (this.isRedrawNeeded(pageNumber)) {
            var startPage = Math.floor((pageNumber - 1) * 0.1) * 10;
            this.showPageNav(startPage + 1);
        }


        var oldPageAnchor = document.getElementById(this.pagerName + 'pg' + this.currentPage);
        if (oldPageAnchor != null) {
            oldPageAnchor.className = 'pg-normal';
        }


        this.currentPage = pageNumber;
        var newPageAnchor = document.getElementById(this.pagerName + 'pg' + this.currentPage);
        if (newPageAnchor != null) {
            newPageAnchor.className = 'pg-selected';
        }


        var from = (pageNumber - 1) * itemsPerPage + 1;
        var to = from + itemsPerPage - 1;
        this.showRecords(from, to);


        var pgNext = document.getElementById(this.pagerName + 'pgNext');
        var pgPrev = document.getElementById(this.pagerName + 'pgPrev');


        if (pgNext != null) {
            if (this.currentPage == this.pages) pgNext.style.display = 'none';
            else pgNext.style.display = '';
        }


        if (pgPrev != null) {
            if (this.currentPage == 1) pgPrev.style.display = 'none';
            else pgPrev.style.display = '';
        }
    }


    this.prev = function () {
        if (this.currentPage > 1) this.showPage(this.currentPage - 1);
    }


    this.next = function () {
        if (this.currentPage < this.pages) {
            this.showPage(this.currentPage + 1);
        }
    }


    this.init = function () {
        var rows = document.getElementById(tableName).rows;
        var records = (rows.length - 1);
        this.pages = Math.ceil(records / itemsPerPage);
        this.inited = true;
    }




    this.isRedrawNeeded = function (pageNumber) {


        for (var i = 0; i < this.numbers.length; i++) {
            if (this.numbers[i] == pageNumber) {
                return false;
            }
        }
        return true;
    }




    this.showPageNav = function (start) {
        if (!this.inited) {
            alert("not inited");
            return;
        }
        var element = document.getElementById(this.positionId);
        var loopEnd = start + 9;
        var index = 0;
        this.numbers = new Array(10);


        var pagerHtml = '<span class=\"regularData\">' + (document.getElementById(this.tableName).rows.length - 1) + ' items found <\span>';


        pagerHtml += '<span onclick="' + this.pagerName + '.showPage(1);" class="pg-normal">First </span>';


        if (this.pages > 10) {
            pagerHtml += '<span id="' + this.pagerName + 'pgPrev" onclick="' + this.pagerName + '.prev();" class="pg-normal"> &#171 Prev </span>|';
        }
        for (var page = start; page <= loopEnd; page++) {


            if (page > this.pages) {
                break;
            }
            this.numbers[index] = page;
            pagerHtml += '<span id="' + this.pagerName + 'pg' + page + '" class="pg-normal" onclick="' + this.pagerName + '.showPage(' + page + ');">' + page + '</span>';
            if (page != loopEnd) {
                pagerHtml += '|';
            }
            index++;
        }
        page--;
        if (this.pages > page) {
            pagerHtml += '<span class="regularDataBlue">...</span>';
        }


        pagerHtml += '<span id="' + this.pagerName + 'pgNext" onclick="' + this.pagerName + '.next();" class="pg-normal"> Next &#187;</span>';
        pagerHtml += '<span onclick="' + this.pagerName + '.showPage(' + this.pages + ');" class="pg-normal"> Last</span>';


        element.innerHTML = pagerHtml;
    }
}




Add this to your html Page.


<script type="text/javascript">


var pager = new Pager('anyTable', 20, 'pager', 'anyDiv');
    pager.init();
    pager.showPage(1);


</script>


Arguments:
1. table Id to paginate
2. number of rows per page.
3. variable name to this class, any name will work.
4. div id where pagination will show.


That's it!







12 comments:

  1. It does work in my case... My table is generated by my servlet that will populate the table and returns the table HTML back, consists of the table tag as well..
    so i included id=\"results\" in the table tag...
    >.<"

    ReplyDelete
  2. Good job and nice update to the script. Really does the job but just one thing, my table actually pulls the content and calculate rank before displaying. What happens when I pull the content, it only sort the ranks of current page content rather than the complete table. Once clicked, it does trigger and sort the complete ranks but can’t see a possible quick way to fix it.

    Thanks for sharing.

    ReplyDelete
  3. very useful code..after longtime i found very easy way to implement pagination thanks

    ReplyDelete
  4. nice... but my code doesn't work... when i clik the page there is error 'pager is not defined'... help me plizz

    ReplyDelete
    Replies
    1. Seems your variable "pager" is not defined before using it. Make sure you define this var 1st, you can do it either the way it is defined above or secondly like that:

      var pager;
      pager = new Pager('anyTable', 20, 'pager', 'anyDiv');

      Let me know if that solves your problem.

      Delete
  5. thats not actually like google. It does not display page numbers >9 and when u go to next its still ....

    ReplyDelete
  6. getting error "Unable to get value of property rows" in pagination.js file

    ReplyDelete
  7. Hi i have used this pagination and modified as i need but i need to know how can i use this same pagination in top and bottom of the same table.please tell me is there any way to change js and do it?

    ReplyDelete
  8. hi, can you send me all code related to pagination.
    My email id is rajivnayan7@gmail.com

    ReplyDelete
  9. Is there any css properties related to css classes 1) regularDataBlue and 2) regularData or are they just used as accessors?

    ReplyDelete