My recent blog post on Creating Paged and Sorted tables in Drupal 7 got a comment today asking if it was possible to implement Paging and Sorting in Drupal tables via Ajax, instead of regular Page refreshes that Drupal does by default.
Why not I thought… Drupal already provides bulk of the server-side framework for the purpose, and Ajax should be a breeze with jQuery. The only thing that would need custom coding would be to hook into the header and paging links and invoke Ajax calls in their click handlers manually, and suppress the page refresh. Then in the server-side code, handle the ajax callback and return the paged and/or sorted table to the browser.
I sat down to write a very simply module demonstrating this entire functionality (which you can find attached). Here I quickly discuss various aspects of the server and client side code for such Ajax paging and sorting.
Let’s call our demo module, mymodule and discuss its server-side code first. Here’s the bulk of the code from the only server-side file: mymodule.module:
{syntaxhighlighter brush: php;fontsize: 100; first-line: 1; }function mymodule_menu(){
$items = array();
//Test items
$items[‘mymodule/test/pager’] = array(
‘title’ => ‘Drupal 7 test pager’,
‘type’ => MENU_CALLBACK,
‘page callback’ => ‘mymodule_test_pager’,
‘access arguments’ => array(‘access content’)
);
$items[‘mymodule/test/pager/callback’] = array(
‘title’ => ‘Test Pager Callback’,
‘type’ => MENU_CALLBACK,
‘page callback’ => ‘_mymodule_test_pager_callback’,
‘access arguments’ => array(‘access content’),
);
return $items;
}
function mymodule_test_pager () {
drupal_add_js(drupal_get_path(‘module’, ‘mymodule’) . ‘/jquery.url.js’);
drupal_add_js(drupal_get_path(‘module’, ‘mymodule’) . ‘/mymodule.js’);
drupal_add_js(‘initializeTable();’, ‘inline’);
return (‘<div id=”table-container”></div>’);
}
function _mymodule_test_pager_callback () {
//This function is invoked on Ajax request and returns the paged and/or sorted table. You can find code for this in the attached zip file below.
}{/syntaxhighlighter}
We have used hook_menu here to define 2 menu router entries, the first is a regular Drupal module page which this module uses to demonstrate the Ajaxed table. And the second is for the callback method that receives the ajax callback request and returns the table html to the browser.
Preparing a table and returning the html is all boilerplate code that has been discussed in detail in the other blog post here. Please consult the other blog post if you need to understand the process. The attached code contains the full implementation of the callback method.
The remaining part is client-side where we hook jQuery click handlers to sorting and paging links and perform the same via an ajax call. Here’s the javascript code for the same:
{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; }function refreshTable(page, sort, order) {
if(!page) page = 0;
if(!sort) sort = ”;
if(!order) order = ”;
jQuery.ajax({
cache: false,
url: Drupal.settings.basePath + ‘?q=mymodule/test/pager/callback’,
data: {page: page, sort: sort, order: order},
dataType: ‘text’,
error: function(request, status, error) {
alert(status);
},
success: function(data, status, request) {
var html = data;
jQuery(‘#table-container’).html(html);
jQuery(‘#table-container th a’).
add(‘#table-container .pager-item a’)
.add(‘#table-container .pager-first a’)
.add(‘#table-container .pager-previous a’)
.add(‘#table-container .pager-next a’)
.add(‘#table-container .pager-last a’)
.click(function(el, a, b, c) {
var url = jQuery.url(el.currentTarget.getAttribute(‘href’));
refreshTable(url.param(‘page’), url.param(‘sort’), url.param(‘order’));
return (false);
});
}
});
}
function initializeTable() {
jQuery(document).ready(function() {
refreshTable();
});
}{/syntaxhighlighter}
Again its pretty standard code that finds desired anchor tags using suitable CSS selectors and then binds a click listener to those anchors to invoke a Ajax call from the click handler.
And voila, you have a completely Ajaxed Paging and Sorting Experience in Drupal 7. To try it, please download the attached zip file, and extract the contents to the “modules” folder of your Drupal installation. Then enable the module from Administration section and test the functionality by visiting http://example.com/mymodule/test/pager in your Drupal installation (replace example.com with the path to your Drupal 7 installation).
It’s pretty similar to achieve such Ajaxed paging and sorting with Drupal 6 also. You can easily combine the code from this blog post and my earlier one regarding Creating Paged and Sorted tables in Drupal 6 to have Ajaxed Paging and Sorting for D6. In case you face an issue doing so with D6, please let me know via comments below and I will try to cough up D6 code also for the same.
Hello!
In the beginning – great JOB!
I’m trying to implement this in D6 but I have a little problem… you’re calling the theme(‘table’…..) like this:
$html = theme(‘table’,
array(
‘header’ => $header,
‘rows’=>$rows,
‘caption’ => ‘Creating Drupal 7 Ajaxed tables’, //Optional Caption for the table
‘sticky’ => TRUE, //Optional to indicate whether the table headers should be sticky
’empty’ => ‘No nodes created…’, //Optional empty text for the table if resultset is empty
)
);
in D6 the correct syntax is: theme (‘table’, $headers, $rows) not theme (‘table’, array()). Could you possibly tell me how to use that in D6 ?
Kind regards,
Jarek
Just want to say thanks for this great post 🙂
It really helps me for a little module that I need this morning!
regards,
MartinO
hi!, Thanks for the Info, Its very clear and step forward,
I have tested the attached module and have found that in this version (ajax-ed) the sticky header is not working.
I have added a form with a collapsible fieldset, wich also have stoped working.
both funcionalities works fine in the non-ajax version.
Could oyu test this issue? I think that there is some incompatibilities with js manually included, but can’t find what is happening, also have noted that in this version drupal does not auto-insert the some table related js (like tableheader.js)
Great job, works like a charm!
it would be super nice if you can edit inline/in place the data of the table…
cheers, maxx
i liked your solution. i would like to reuse it and extend. The functionality i miss – is filtering.
Do you plan to add it? Or can you share some ideas of how would you do it? any help appreciated.
p.s. i was trying to do it by myself by adding simple html form with filter-fields. The problem i could not solve is that i cannot see any $_POST or $_GET attributes in the _mymodule_test_pager_callback method. Still haven’t discovered why 🙁
I really appretiate your effort. You did a great favour.
really really helpful – ur a great man! THANKS!!!
ps if I ever get my business super successful i’m hiring you!!!
Thanks for sharing, really added that extra sparkle to my data table. One thing though, in my data table I had some links that opened a dialog modal, so I needed to re-attach the behaviours to those links after the table was added in your jquery.
before:
jQuery(‘#table-container’).html(html);
after:
jQuery(‘#table-container’).html(html);
Drupal.attachBehaviors(‘#table-container’);
Also, did you have any thoughts on adding an ajax loader when the pagers are clicked. I’ll probably try and figure it out, if I do I’ll post the solution here.
Thanks again for sharing.
Thanks, thetoast. This saved me a ton of time:
Drupal.attachBehaviors(‘#table-container’);
Thanks for the tutorial.
But how can I add 2 different ajax paged tables on 1 page?
In my site i have to try to implete your module its works great, by my accordion is not working, tables are listing under accordian. there are three table in one page and i need accordion and ajax pager both together.
Hi
Need a help for Multiple pager (unique) with Table header sorting (unique) in a single page
Table 1: published nodes with table header “nid”, “Title” – limit is 5, Total 20 nodes
Table 2: unpublished nodes with table header “nid”, “Title” – Limit is 10, Total 50 nodes
If i do sorting in table 2 “nid” column then only table 2 is needs to sort. Table 1 should not sorts.
Thanks in advance
Hi,
I am trying to do the same in for block instead of page. But I am unable to understand how to do this for block.
Thanks
Amit
ajax_table module
Live examples and using (rus)
http://engear.ru/projects/ajax-table
Download
https://github.com/player259/ajax_table
Ajax table + sort, pager, tabledrag + some useful features (tabledrag sections and level-restrictions)
Great tutorial.
I have a question.