How to Use DataTables to Display AJAX Loaded Content in WordPress

Today, we are going to create an AJAX powered posts table in WordPress with DataTables. For the purpose of this post, we’re going to assume you’re in a custom theme or a child theme and are ready to jump into things with your favorite IDE. To do this, we need to enqueue DataTables’ assets, set up some AJAX handlers to respond to the requests, and finally put our table element into place and call DataTables into action. Here’s how to use DataTables to display AJAX loaded content in WordPress:

1. Get DataTables Into Your Theme

First, let’s grab DataTables’ CSS & JS. There’s a CDN for that, as detailed on the DataTables download page. We’re just using the basics for now, so throw this in your functions.php to get them enqueued. And, while you’re here, go ahead and localize the path to admin-ajax.php as datatablesajax.url:

function datatables_scripts_in_head(){
  wp_enqueue_script('datatables', '', array('jquery') );
  wp_localize_script( 'datatables', 'datatablesajax', array('url' => admin_url('admin-ajax.php')) );
  wp_enqueue_style('datatables', '' );
add_action('wp_enqueue_scripts', 'datatables_scripts_in_head');

2. Declare Functions to Handle DataTables’ AJAX Requests

Now, let’s declare some functions to handle the AJAX requests that DataTables is going to be sending later. Take note of our AJAX action “getpostsfordatatables” as we’ll reference it again later. In this example, we’re getting the first 100 posts, but the query can easily be expanded to get more. We’re returning basic post data as well, but this could just as well include postmeta, taxonomy data, etc.

add_action( 'wp_ajax_getpostsfordatatables', 'my_ajax_getpostsfordatatables' );
add_action( 'wp_ajax_nopriv_getpostsfordatatables', 'my_ajax_getpostsfordatatables' );

function my_ajax_getpostsfordatatables() {
  global $wpdb;

  //some basic query arguments
  $posts_per_page = 100;
  $page = 1;
  $args = array(
    'post_type'             => 'post',
    'posts_per_page'        => $posts_per_page,
    'paged'                 => $page

  $postsQ = new WP_Query( $args );
  //create empty array and loop through results, populating array
  $return_json = array();
  while($postsQ->have_posts()) {
    $row = array(
      'id' => get_the_ID(),
      'title' => get_the_title(),
      'author' => get_the_author(),
      'date' => get_the_date('Y-m-d'),
      'excerpt' => strip_tags(get_the_excerpt()),
      'link' => get_permalink()
    $return_json[] = $row;

  //return the result to the ajax request and die
  echo json_encode(array('data' => $return_json));

3. Create a Table and Initialize DataTables

Now, jump into a page template, or a shortcode function, or a content filter, or whatever you have that can get some HTML and JavaScript into wherever you want this table to appear on the frontend. This is where you want to create your table. Here is some basic table markup with column headers to get you started:

<table id="table" width="100%">
    <tr role="row">

Now, let’s initialize this, define the AJAX url as datatablesajax.url, which is that variable we localized earlier, also specifying the action “getpostsfordatatables” so WordPress handles our request with the function defined earlier. Take note of the extra DataTable() argument ‘columnDefs’ to format the link as an actual clickable link rather than displaying the URL returned in the request. If your table shows up on more than one place in your site, maybe this should be enqueued as its own separate .js file, but this works too.

jQuery(document).ready(function($) {
  var jobtable = $('#table').DataTable({
    ajax: {
      url: datatablesajax.url + '?action=getpostsfordatatables'
    columns: [
        { data: 'id' },
        { data: 'title' },
        { data: 'author' },
        { data: 'date' },
        { data: 'excerpt' },
        { data: 'link' }
    columnDefs: [
            "render": function (data, type, row) {
            return '<a href="' + data + '">Read this post</a>';
            "targets": 5


And, there you have it – a basic posts table. Maybe you can use it for a custom post type, or to display content from a custom table, or to display more data related to a single post. Should we update this article to include more complicated post filtering with meta queries, dynamically updating the results, or anything else? Leave a comment to let us know and we’ll get around to it eventually!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.