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.
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
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
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
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?
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.
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
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/