jQuery Plugin: tablePager

Here’s a quick table pager plugin for jQuery. Unlike a number of the other plugins out there, this one doesn’t alter the DOM tree of the table itself it just hides the rows that are not available for the current page. In this way you can still get access to all the elements of the table throughout the lifetime of the page.

Plugin Source:

(function($) {
    $.fn.tablePager = function(options) {
 
        /*
        options = {
        firstBtn: Element,
        prevBtn: Element,
        nextBtn: Element,
        lastBtn: Element,
        indicator: Element,
        sizeSelect: Element,
        pageSize: Number,
        onPageChange: Callback,
        onPageSizeChange: Callback
        };
        */
 
        var tbl = this;
        var defaults = { pageSize: 10 };
        var opts = $.extend(defaults, options);
 
        var pageIndex = 0;
        var pageSize = opts.pageSize;
        var rowCount = getRows().length;
        var pageCount = getPageCount();
 
        function init() {
            bindControlHandlers();
            updatePaging();
            updateIndicator();
        }
 
        function getRows() {
            return tbl.find("tbody tr");
        }
 
        function bindControlHandlers() {
            if (opts.firstBtn) { 
	        opts.firstBtn.unbind().bind("click", 
		    function() { changePage(0); }); 
            }
            if (opts.prevBtn) { 
		opts.prevBtn.unbind().bind("click", 
			function() { changePage(pageIndex - 1); }); 
	    }
            if (opts.nextBtn) { 
		opts.nextBtn.unbind().bind("click", 
			function() { changePage(pageIndex + 1); }); 
	    }
            if (opts.lastBtn) { 
		opts.lastBtn.unbind().bind("click", 
			function() { changePage(pageCount - 1); }); 
	    }
            if (opts.sizeSelect) { 
		opts.sizeSelect.unbind().bind("change", 
                    function() { changePageSize(parseInt($(this).val())); }); 
	    }
        }
 
        function getPageCount() {
            return (rowCount % pageSize) ? 
		Math.floor(rowCount / pageSize) + 1 : (rowCount / pageSize);
        }
 
        function changePage(toIndex) {
            if (toIndex >= 0 && toIndex <= (pageCount - 1)) {
                pageIndex = toIndex;
                updatePaging();
                updateIndicator();
                if (opts.onPageChange) {
                    opts.onPageChange.call(pageIndex);
                }
            }
        }
 
        function changePageSize(toSize) {
            pageSize = toSize;
            pageCount = getPageCount();
            updatePaging();
            updateIndicator();
            if (opts.onPageSizeChange) {
                opts.onPageSizeChange.call(pageSize);
            }
        }
 
        function updateIndicator() {
	    if (opts.indicator) {
            	opts.indicator.val((pageIndex + 1) + "/" + pageCount);
	    }
        }
 
        function updatePaging() {
            var start = pageIndex * pageSize;
            var end = start + pageSize;
            var i = 0;
            var rows = getRows();
            rows.each(function() {
                if (i >= start && i < end) {
                    $(rows[i]).show();
                } else {
                    $(rows[i]).hide();
                }
                i++;
            });
        }
 
        init();
 
        return {
            changePage: function(moveTo) { changePage(moveTo - 1); },
            getPageSize: function() { return pageSize; },
            getPageIndex: function() { return pageIndex; }
        };
    };
})(jQuery);

Usage:

var pager = $("#testTable").tablePager({
    firstBtn: $(".first"), // The element that pages to the first page
    prevBtn: $(".prev"), // The element that pages to the previous page
    nextBtn: $(".next"), // The element that pages to the next page
    lastBtn: $(".last"), // The element that pages to the last page
    indicator: $(".curpage"), // The input element that stores the current page (i.e. "1/5")
    sizeSelect: $(".pagesize"), // The select element that indicates the current page size
    pageSize: 5, // The initial page size
    onPageChange: function(newIndex) { alert(newIndex); }, // Page change callback
    onPageSizeChange: function(newSize) { alert(newSize); } // Page size change callback
});
 
pager.changePage(2); // Causes the page to change from outside the plugin
var pageIndex = pager.getPageIndex(); // Returns the current page index
var pageSize = pager.getPageSize(); // Returns the current page size

And here’s some example markup for the pager elements:

<span class="first">First</span>&nbsp;&nbsp;
<span class="prev">Prev</span>&nbsp;&nbsp;
<span class="next">Next</span>&nbsp;&nbsp;
<span class="last">Last</span>
<br><br>
<input type="text" class="curpage" />&nbsp;&nbsp;
<select class="pagesize">
    <option value="5">5</option>
    <option value="10">10</option>
    <option value="20">20</option>
</select>

As you can see it’s really simple and flexible. You can supply any elements you want to the pager. If you don’t supply a first and last button elements for example then those will be ignored, if you don’t specify an indicator then that will be ignored too. The most important thing is that your DOM stays intact, this allows you to continue to manipulate the “hidden” portions of the table (i.e. the stuff not on the current page) without having to access some crazy expando property that other pager plugins use to stash the un-shown portions of the table.

As always, I’d appreciate any feedback.

Category: JavaScript, jQuery 2 comments »

2 Responses to “jQuery Plugin: tablePager”

  1. Frank

    You need to show an example of the plug/code working. ;)

    Great job!!!
    //fd3

  2. chris

    does work in ie


Leave a Reply



Back to top