Both DataTables Editor and WordPress are trying to use the same reserved parameter, ‘action’.
WordPress is using $_REQUEST[‘action’] to route the request in admin-ajax.php line 86.
DataTables Editor is using $_POST[‘action’] to tell the server-side processing script what action to apply ( insert / delete / update – see: https://editor.datatables.net/manual/server )
This would work fine if $_REQUEST[‘action’] was set to ‘datatables’. However, WordPress forces $_REQUEST to be GET + POST on line 598 of wp-includes/load.php
function wp_magic_quotes() {
// If already slashed, strip.
if ( get_magic_quotes_gpc() ) {
$_GET = stripslashes_deep( $_GET );
$_POST = stripslashes_deep( $_POST );
$_COOKIE = stripslashes_deep( $_COOKIE );
}
// Escape with wpdb.
$_GET = add_magic_quotes( $_GET );
$_POST = add_magic_quotes( $_POST );
$_COOKIE = add_magic_quotes( $_COOKIE );
$_SERVER = add_magic_quotes( $_SERVER );
// Force REQUEST to be GET + POST.
$_REQUEST = array_merge( $_GET, $_POST );
}
Thus, your ajax callback function is never being called.
What you need to do is add the following:
add_action('admin_init', 'fix_request_action');
function fix_request_action() {
global $pagenow;
if($pagenow == 'admin-ajax.php' && isset($_GET['action']) && isset($_POST['action'])) {
$_REQUEST['action'] = $_GET['action'];
}
}
This will detect the situation where both $_GET[‘action’] and $_POST[‘action’] are set when the current page is admin-ajax.php. It will force $_REQUEST[‘action’] to be the correct action (in your case, ‘datatables’ – the $_GET action) so that your callback will be called correctly.
I hope this helps.