Skip to main content

Datatables and Wordpress Integration problem solved.


Note: Download a working demo plugin from this project's github repository.

Like other wordpress developers, I had also faced the problem of integrating datatable(server side processing) with wordpress. I tried every tips, tricks and multiple ways to solve the problem, but couldn't do it. My ajaxified functions of the wordpress simple dint work. I din't have much time and had to finish a small project on time. So, I decided to skip it and go through the developer's way : the plugin developer had suggested and implemented.

I dropped the required php file with some related modifications and called the url of the php file in the datatable options in my project. It worked after few small hiccups. I wasn't satisfied though, as i wanted the wordpress centric solution, instead of using some drop-in file to complement the functionality. I had vowed to look after this problem whenever I could get some time.




(You may visit the url http://www.bearinghouse.net/order-now/ to see it working. It is working with the drop-in php file with some modifications). Correction: It is working with the Ajaxified Wordpress Solutions discussed below.


Actually, to tell you the truth, I am lazy. I want to solve the problem in such a way that I do not have to spend too much time on that. Due to this laziness of mine, I am always on the lookout for sneaky ways to get the job done quickly. Though, I never sacrifice quality, and usefulness because of my laziness.

So, like I said, I wanted to revisit the problem I had faced with datatable and wordpress earlier.

As mentioned earlier, I was not satisfied with the drop-in php file and wanted to fully integrate server side processing feature of datatable with wordpress. So, I started researching again and read the following articles to get inspired.

http://datatables.net/forums/discussion/6759/wordpress-integration/p1
http://datatables.net/release-datatables/examples/server_side/post.html
http://datatables.net/release-datatables/examples/server_side/server_side.html
http://wp.smashingmagazine.com/2011/10/18/how-to-use-ajax-in-wordpress/
http://codex.wordpress.org/AJAX_in_Plugins
http://www.garyc40.com/2010/03/5-tips-for-using-ajax-in-wordpress/

and suddenly it clicked that I had been looking at the problem with a generalized view. So much for my lateral thinking training. Lets get back to our code editors to see how I solved the problem. I am using the same datatable used in all examples here.

My js code for datatable is:
oTable = jQuery('#example').dataTable({
   "bProcessing": true,
   "bServerSide": true,
   "sAjaxSource": ajaxurl+'?action=fn_my_ajaxified_dataloader_ajax',
   "bDeferRender": true,
   "fnServerData": fnDataTablesPipeline,
"bScrollInfinite": true,
        "bScrollCollapse": true,
        "sScrollY": "200px"
});

My Wordpress PHP Code:

Define Ajax Actions

add_action('wp_ajax_fn_my_ajaxified_dataloader_ajax', 'fn_my_ajaxified_dataloader_ajax');
add_action('wp_ajax_nopriv_fn_my_ajaxified_dataloader_ajax', 'fn_my_ajaxified_dataloader_ajax');

Now the wordpress Function

function fn_my_ajaxified_dataloader_ajax()
{
global $wpdb;

$aColumns = array( 'engine', 'browser', 'platform', 'version', 'grade' );
$sIndexColumn = "id";
$sTable = "ajax";

$sLimit = "";
if ( isset( $_REQUEST['iDisplayStart'] ) && $_REQUEST['iDisplayLength'] != '-1' )
{
$sLimit = "LIMIT ".intval( $_REQUEST['iDisplayStart'] ).", ".
intval( $_REQUEST['iDisplayLength'] );
}

$sOrder = "";
if ( isset( $_REQUEST['iSortCol_0'] ) )
{
$sOrder = "ORDER BY  ";
for ( $i=0 ; $i<intval( $_REQUEST['iSortingCols'] ) ; $i++ )
{
if ( $_REQUEST[ 'bSortable_'.intval($_REQUEST['iSortCol_'.$i]) ] == "true" )
{
$sOrder .= "`".$aColumns[ intval( $_REQUEST['iSortCol_'.$i] ) ]."` ".
($_REQUEST['sSortDir_'.$i]==='asc' ? 'asc' : 'desc') .", ";
}
}

$sOrder = substr_replace( $sOrder, "", -2 );
if ( $sOrder == "ORDER BY" )
{
$sOrder = "";
}
}

$sWhere = "";
if ( isset($_REQUEST['sSearch']) && $_REQUEST['sSearch'] != "" )
{
$sWhere = "WHERE (";
for ( $i=0 ; $i<count($aColumns) ; $i++ )
{
$sWhere .= "`".$aColumns[$i]."` LIKE '%".esc_sql( $_REQUEST['sSearch'] )."%' OR ";
}
$sWhere = substr_replace( $sWhere, "", -3 );
$sWhere .= ')';
}

for ( $i=0 ; $i<count($aColumns) ; $i++ )
{
if ( isset($_REQUEST['bSearchable_'.$i]) && $_REQUEST['bSearchable_'.$i] == "true" && $_REQUEST['sSearch_'.$i] != '' )
{
if ( $sWhere == "" )
{
$sWhere = "WHERE ";
}
else
{
$sWhere .= " AND ";
}
$sWhere .= "`".$aColumns[$i]."` LIKE '%".esc_sql($_REQUEST['sSearch_'.$i])."%' ";
}
}

$sQuery = "
SELECT SQL_CALC_FOUND_ROWS `".str_replace(" , ", " ", implode("`, `", $aColumns))."`
FROM   $sTable
$sWhere
$sOrder
$sLimit
";
$rResult = $wpdb->get_results($sQuery, ARRAY_A);

$sQuery = "
SELECT FOUND_ROWS()
";
$rResultFilterTotal = $wpdb->get_results($sQuery, ARRAY_N);
$iFilteredTotal = $rResultFilterTotal [0];

$sQuery = "
SELECT COUNT(`".$sIndexColumn."`)
FROM   $sTable
";
$rResultTotal = $wpdb->get_results($sQuery, ARRAY_N);
$iTotal = $rResultTotal [0];

$output = array(
"sEcho" => intval($_REQUEST['sEcho']),
"iTotalRecords" => $iTotal,
"iTotalDisplayRecords" => $iFilteredTotal,
"aaData" => array()
);

foreach($rResult as $aRow)
{
$row = array();
for ( $i=0 ; $i<count($aColumns) ; $i++ )
{
if ( $aColumns[$i] == "version" )
{
$row[] = ($aRow[ $aColumns[$i] ]=="0") ? '-' : $aRow[ $aColumns[$i] ];
}
else if ( $aColumns[$i] != ' ' )
{
$row[] = $aRow[ $aColumns[$i] ];
}
}
$output['aaData'][] = $row;
}

echo json_encode( $output );
die();
}

This conversion may not be perfect, but atleast it is letting me do my job. Yes, I am using $_REQUEST. It worked the first time, so I dint try $_POST. Why don't you try that and let me know so that I can mention here that $_POST works.

Hope you can get it to work. If not let me know and I'll fix your problem or guide you in the right direction.

Niraj Kumar

*Update : It seems that I should also have used ARRAY_N instead of ARRAY_A. Well, the above code is fixed now. No problems anymore.
*Update: I missed the bugs. Thanks Naab for pointing out the problems.
* Update: Yes Post works too.

Comments

Anonymous said…
Hi Niraj,
After searching entire web for integration point of wordpress and datatables I found only your blog promising enough. I tried all the codes you provided but nothing happened. My datatable on page doesn't get populated with data from ajax table in database.

Can you put some more light as to where you have dropped extra piece of code.
URL of the page I am trying to get this : http://cosmolibrary.novamining.com/datatables-wordpress/
PHP codes you mentioned in you blog are appended in function.php

Btw, I have become you fan after seeing what you have done at http://www.bearinghouse.net/order-now/
Simple looking software but rich in navigation.


Best Regards,
Deepak
Unknown said…
Dear Deepak,
Sure, I can help you, but you need to share your datatable connection code, so that I can understand where you've missed. You can mail me (nirajkvinit@yahoo.co.in) your problematic portion of your code.
Awaiting your reply,
regards,
Niraj Kumar
Jenny said…
Hi Niraj,

I have datatables setup on a WordPress website. On the page which displays the table I initialize the table with almost no options. Except for using fnServerParams this sends the action to admin-ajax.php. An example is

"sAjaxSource":'http://example.com/wp-admin/admin-ajax.php',

"fnServerParams": function ( aoData ) {
aoData.push({ "name": "post_id", "value":'' } );
}

On the same page as the table I have a form which also posts using AJAX and an action to create a new post.

When I create a new post within the AJAX success I have dataTable().fnReloadAjax();

The table begins showing Processing then freezes.

In my console I see sError and that no json is returning.

So to be clear there are two actions, one which creates posts from the form on the page with the datatable. Another action generates the json file. When the page loads the AJAX call with action to load the json fires right away generating the table.

Now after I create a post, why isn't fnReloadAjax getting the json file again from the first action? It seems as if fnServerParams is not being sent? Do you have any ideas on what I can try? Should I create a new action ie; add_action(add_post,get_table); so when a post is added using the form it fires the action to generate the table? But I would think that happens when a post is created because of fnReloadAjax?

Unknown said…
Hello Jenny,
Since I can't see your code, I am in dark. Still, read below.

1. Your Ajax Source should be-
"sAjaxSource": ajaxurl+'?action=fn_my_ajaxified_dataloader_ajax'

Since you are directly using the adminajax, so your sAjaxSource should be -
"sAjaxSource":'http://example.com/wp-admin/admin-ajax.php?action=fn_my_ajaxified_dataloader_ajax',


2. Define Ajax Actions:
You should add the ajax actions in your PHP code for the logged-in and logged-out users. Well, actually if you do not want to show your data to anonymous visitors, then you can just use normal add_action which is:
add_action('wp_ajax_fn_my_ajaxified_dataloader_ajax', 'fn_my_ajaxified_dataloader_ajax');

For Anonymous Visitors:
add_action('wp_ajax_nopriv_fn_my_ajaxified_dataloader_ajax', 'fn_my_ajaxified_dataloader_ajax');


3. Now the wordpress Function

function fn_my_ajaxified_dataloader_ajax()
{
//PHP code for data retrieval and json output as explained in the post.
}

Above actions should see some ajax codes or maybe some errors which you can .

Note:
You Question: Now after I create a post, why isn't fnReloadAjax getting the json file again from the first action?

Answer - To reiterate, until I see the code or get more info about the scenario, my probable guess would be that the server param is not getting the right variable value or not getting it at all.

In my another project I had to perform similar action:
"fnServerParams": function ( aoData )
{
aoData.push
(
{"name": "current_selected_company","value": $current_company }
);
},

And for that i had been using fnFilter instead of fnReloadAjax (which shouldn't be required). While calling fnFilter I made sure to update $current_company variable value before the fnFilter call. I had to make $current_company public so that my datatable function and the filtering functions(JS) both can access it. While filter function changed the value, the datatable retrieved the changed value from the variable and pushed it to the PHP function through fnServerParams where the filtering occurs based on the pushed value.

I hope, I didn't make you more confused. Do let me know if it helped or not or whether you require more help.
Melissa K said…
Hi Niraj -
Great post, nicely done. I am drawing upon your material in building a site for our local school.

Would you have anything handy to help us with Create, Update & Delete?

thank you
Melissa
Unknown said…
Greetings Melissa!
I am not exactly sure about your requirement. Yet what I have perceived is you require a Datagrid for creating/updating/deleting row data. Perhaps these might interest you:
Datatables Editor - http://editor.datatables.net/
Flexigrid - http://flexigrid.info/
jqGrid - http://www.trirand.net/demo/php/jqgrid/
Melissa K said…
Thanks Niraj - will check those.

Popular posts from this blog

Installing Oracle 9i on RHEL5. (x86)

I must warn you that this article is as it is. It worked when I was installing the combo - a long time ago. I am not sure about the links available in this article. I am not maintaining this article anymore, (other than sprucing it up a bit for better reading). I am completely out of touch with RHEL or Oracle for that matter. Still, dont lose your heart yet. I am sure, with proper searching using the big brother - Google, you will find lots of more information relating to your work to help you finish what you are doing. Foreword Recently I joined Sqlstar International for my Oracle DBA course. Everything was going smooth. I completed my SQL Fundamentals with Oracle installed on Windows in my pc. But when classes started for DBA Fundamentals 1 I was at loss, as in my institute oracle was installed on Redhat Linux platform. I could have done all the solution of the text on windows but I decided to configure my own Linux box and install oracle on it to simulate the class environment.

Web Development Dilemma - Part 2

Recently, I got a Job to build an ERP Application (More like Accounting Package with CRM). I started planning for the Application. I had some experience with Tally.ERP 9 and knew a bit about Accounting too. Once again I chose Wordpress Platform for the application development, as I was more comfortable with it. Application was to have multiple advanced features along with some of smart automated data sensing and processing, and selective data push (Semi-Automated) to Tally for Accounting Purpose. The application was to run in a LAN Environment and was connected with the Customer's Website to retrieve Customer Order submitted on the website (Customized Shopping Cart) for further processing.  I could develop fast in Wordpress, I was familiar with the system and environment. But due to multiple distractions, and tedious job (I hadn't anticipated lengthy coding and timing involved), the project had to be scrapped by the customer. The customer was gracious enough to forgive me