jqGrid: Custom Pagination
Being a big fan of jqGrid, I implement it in almost all my projects where the conventional listing is required. Our wonderful UI team then takes it further by beautifying it as per the design needs. Every portion of jqGrid is themeble to such an extent that we never needed to make any extra efforts to make it look better. But all these years, there’s only one thing that I found really ugly (!) in jqGrid – its pagination bar. It never goes well with the custom design which mostly expects a cool looking paging style instead of the drop-down and the text box for pagination.
The need to change this finally came up very prominently in one of my current projects and I started off as usual by Google’ing for help. Surprising, I got very less help in regards to changing the complete look and feel of the pagination. Most of them including the official jqGrid wiki page for pagination only talked about changing the display format of current components on pagination section. Finally, one of the posts on Stackoverflow talked about replacing the current pagination in DOM with a new one and linking it to grid. I decided to take that approach which would also give a complete freedom of implementing my own custom pagination logic for jqGrid.
I used loadComplete callback of jqGrid to remove default pagination and replaced it with my custom HTML code created using jQuery.
To begin with, add the following in your loadComplete to remove default pagination
jQuery("#pager').html('');
Next, get the total page count and call your custom pagination function to build the pagination list whatever way you want
var pageCount = Math.ceil(totalData / $("#mygrid').getGridParam("rowNum"));
if (pageCount > 1) {
var custom_pager = BuildGroupedPagination(parseInt(this.p.page), pageCount, 'mygrid');
jQuery("#pager').append(custom_pager);
}
The function BuildGroupedPagination() now has the responsibility to creating the HTML for pagination, attaching events to each page number and returning the whole structure back to be added in place of existing pagination that we removed above. Following is my implementation of BuildGroupedPagination(). You can use the same or write your own if your application demands something else.
function BuildGroupedPagination(current_page, total_pages, gridId)
{
var strPages = "";
var intMaxPages = 0;
var intMinPages = 0;
var intPaginI = 0;
var li;
var link;
var myPageRefresh = function(e) {
var newPage = $(e.target).text();
$("#"+gridId).trigger("reloadGrid",[{page:newPage}]);
e.preventDefault();
};
var custom_pager = $('<ul>', {id: 'custom_pager', class: 'clearfix'});
if (total_pages > 10)
{
if (total_pages > 3)
{
intMaxPages = 3;
}
else
{
intMaxPages = total_pages;
}
for (intPaginI = 1; intPaginI <= intMaxPages; intPaginI++)
{
link = jQuery('<a>', {href:'#', click:myPageRefresh});
link.text(String(intPaginI));
if (intPaginI == current_page)
{
current = 'current_page';
}
else
{
current = '';
}
li = jQuery('<li>', {id: current}).append(link);
jQuery(custom_pager).append(li);
}
if (total_pages > 3)
{
if ((current_page > 1) && (current_page < total_pages))
{
if (current_page > 5)
{
li = jQuery('<li>', {'class': 'pageMiddle'}).append('...');
jQuery(custom_pager).append(li);
}
if (current_page > 4)
{
intMinPages = current_page;
}
else
{
intMinPages = 5;
}
if (current_page < total_pages - 4)
{
intMaxPages = current_page;
}
else
{
intMaxPages = total_pages - 4;
}
for (intPaginI = intMinPages - 1 ; intPaginI <= intMaxPages + 1; intPaginI++)
{
link = jQuery('<a>', {href:'#', click:myPageRefresh});
link.text(String(intPaginI));
if (intPaginI == current_page)
{
current = 'current_page';
}
else
{
current = '';
}
li = jQuery('<li>', {id: current}).append(link);
jQuery(custom_pager).append(li);
}
if (current_page < total_pages - 4)
{
li = jQuery('<li>', {'class': 'pageMiddle'}).append('...');
jQuery(custom_pager).append(li);
}
}
else
{
li = jQuery('<li>', {'class': 'pageMiddle'}).append('...');
jQuery(custom_pager).append(li);
}
for (intPaginI = total_pages - 2; intPaginI <= total_pages; intPaginI++) {
link = jQuery('<a>', {href:'#', click:myPageRefresh});
link.text(String(intPaginI));
if (intPaginI == current_page) {
current = 'current_page';
}
else {
current = '';
}
li = jQuery('<li>', {id: current}).append(link);
jQuery(custom_pager).append(li);
}
}
}
else
{
for (intPaginI = 1; intPaginI <= total_pages; intPaginI++)
{
link = jQuery('<a>', {href:'#', click:myPageRefresh});
link.text(String(intPaginI));
if (intPaginI == current_page)
{
current = 'current_page';
}
else
{
current = '';
}
li = jQuery('<li>', {id: current}).append(link);
jQuery(custom_pager).append(li);
}
}
return custom_pager;
}
The above logic is based on the code provided at Shawson’s blog. A big thanks to him for saving my few hours of coding
.
Now, with the pagination logic in place, you can write your own CSS to match your theme/layout. Here’s how it look in my case
I would love to see your comments if you know the better approach for doing the same or any ways to improve the above implementation.

