How to send AJAX request from WordPress theme

AJAX makes easier to perform operations without submitting the form like – fetch, insert, delete records from MySQL database, file uploading, etc.

Using AJAX in WordPress is a little different. Here, need to consider two things –

  • AJAX sent URL should be admin-ajax.php.
  • wp_ajax action hooks.

In this tutorial, I show how you can handle AJAX request in your WordPress theme.

How to send AJAX request from WordPress theme


Contents

  1. Table Structure
  2. functions.php
  3. Page Template
  4. Create new Page
  5. Output
  6. Conclusion

1. Table Structure

I am using users table in the example.

CREATE TABLE `users` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `username` varchar(100) NOT NULL,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

2. function.php

Open theme functions.php file.

Here, create a users_details_callback() function to handle AJAX requests.

  • If request == 1 – Fetch all records from users table.
  • If request == 2 – Fetch record from users table according to $userid.

Define two actions in set patterns –

  • wp_ajax_[action-name]
  • wp_ajax_nopriv_[action-name]

[action-name] is users_details and pass users_details_callback method name as second parameter.

/* AJAX requests */
add_action( 'wp_ajax_users_details', 'users_details_callback' );
add_action( 'wp_ajax_nopriv_users_details', 'users_details_callback' );
function users_details_callback() {
  global $wpdb;
  
  $request = $_POST['request'];
  $response = array();
  // Fetch all records
  if($request == 1){
    $response = $wpdb->get_results("select id,username from users");
  }
  // Fetch record by id
  if($request == 2){
    $userid = $_POST['userid'];
    $response = $wpdb->get_results("select name,username,email from users where id=".$userid);
  }
 
  echo json_encode($response);
  wp_die(); 
}

3. Page Template

Create a new directory template and a newpage.php file.

HTML

A <select> element and <div id='userDetails'> container.

In the <select> add option using jQuery AJAX and display selected user details in <div id='userDetails'>.

Script

Define ajax_url variable and assign <?= admin_url('admin-ajax.php'); ?>.

Set 'action': 'user_details' and 'request': 1.

Send AJAX request where pass url: ajax_url, data: data. On successfully callback loop on response and append <option> in the <select>.

If value change in the <select> element then send AJAX request where pass selected value and on successful callback update <span> values.

Completed Code

<?php
/* Template Name: New page template */

get_header();
global $wp,$post,$wp_query;

?>
<div class='wrap'>
  <select id='sel_users'></select>

  <br/>
  <div id='userDetails' style='display: none;'>
   <table>
     <tr>
      <td>Name</td>
      <td>: <span id='span_name'></span></td>
     </tr>
     <tr>
      <td>Username</td>
      <td>: <span id='span_username'></span></td>
     </tr>
     <tr>
      <td>Email</td>
      <td>: <span id='span_email'></span></td>
     </tr>
   </table>
  </div>

</div>

<!-- Script -->
<script type='text/javascript'>
jQuery(document).ready(function($){
  var ajax_url = "<?= admin_url('admin-ajax.php'); ?>";
 
  var data = {
   'action': 'users_details',
   'request': 1
  };

  $.ajax({
    url: ajax_url,
    type: 'post',
    data: data,
    dataType: 'json',
    success: function(response){

      $('#sel_users').empty();
      $('#sel_users').append("<option value='0'>-- Select user --</option>");
      var len = response.length;
      for(var i=0; i<len; i++){
        var id = response[i].id;
        var username = response[i].username;

        // Add option
        var option = "<option value='"+id+"'>" + username + "</option>";
        $("#sel_users").append(option);
      }
    }
  });
 
  $('#sel_users').change(function(){
    var id = $(this).val();
    var data = {
     'action': 'users_details',
     'request': 2,
     'userid': id
    };

    $.ajax({
      url: ajax_url,
      type: 'post',
      data: data,
      dataType: 'json',
      success: function(response){
 
        var len = response.length;
        if(len > 0){
          $('#userDetails').show();

          $('#span_name').text(response[0].name);
          $('#span_username').text(response[0].username);
          $('#span_email').text(response[0].email);
        }else{
          $('#userDetails').hide();
        }
      }
    });
  });
});
</script>
<?php

get_footer();

4. Create new Page

  • Login to WordPress Admin dashboard.
  • Navigate to Pages->Add New.
  • Select New page template from Page Attributes section.

How to send AJAX request from WordPress theme

  • Click Publish.

5. Output

It gives following output –

How to send AJAX request from WordPress theme


6. Conclusion

Create a new function in functions.php file to handle AJAX request and add actions wp_ajax_[action-name] and wp_ajax_nopriv_[action-name].

Now use your defined [action-name] in the jQuery.

Always end AJAX function with wp_die(), die(), or exit() methods.

If you found this tutorial helpful then don't forget to share.

16 thoughts on “How to send AJAX request from WordPress theme”

  1. Hi
    I can’t get this to work. Am using a child theme so have tried adding part 2 above to both functions.php in the child theme and the parent theme.
    Server log shows no errors.
    The drop down menu on the page I have created lists no users.
    What might I be doing wrong?

    Reply
    • Sorry pressed post too early. I meant to add that I had tried but got confused because as far as I can tell the correct way to do it would be to add it to the data array:

      $ajax_data = array(
      ‘url’ => admin_url( ‘admin-ajax.php’ ),
      ‘nonce’ => wp_create_nonce( ‘my_nonce_here’ ),
      );

      But in your example, the array is in JS not PHP. Could it be done another way?

      Reply
      • You can store nonces either in meta tag or in hidden field using wp_create_nonce( ‘my_nonce_here’ ). Use ajaxSetup to send it with each AJAX request like this – $.ajaxSetup({headers: {‘X-CSRF-TOKEN’: nonce}});. Here, nonce is a variable name in which assign the value of nonces from the element. You only need to add ajaxSetup once on the page at the script start.

  2. Thanks for that. I’m getting there!
    In my page template I have:
    jQuery(document).ready(function($) {
    var nonce = $(‘meta[name=”csrf-token”]’).attr(‘content’);
    $.ajaxSetup({headers: {‘X-CSRF-TOKEN’: nonce}});
    });
    then in functions.php I have
    function add_general_nonce()
    {
    $nonce = wp_create_nonce( ‘my_general_nonce’ );
    echo “”;
    }
    // To add to front-end pages
    add_action( ‘wp_head’, ‘add_general_nonce’ );
    // To add to admin pages
    add_action( ‘admin_head’, ‘add_general_nonce’ );
    and also in functions.php this:
    function verify_general_nonce()
    {
    $nonced = isset( $_SERVER[‘HTTP_X_CSRF_TOKEN’] )
    ? $_SERVER[‘HTTP_X_CSRF_TOKEN’]
    : ”;
    if ( wp_verify_nonce( $nonced, ‘my_general_nnce’ ) ) {
    echo “alert(‘”. $_SERVER[‘HTTP_X_CSRF_TOKEN’] . “‘)”;

    die();
    }
    }
    And in my admin-ajax.php I have:
    function my_action() {
    verify_general_nonce();
    }
    add_action( ‘wp_ajax_nopriv_my_action’, ‘my_action’ );
    add_action( ‘wp_ajax_my_action’, ‘my_action’ );

    The drop down menu works, but I don’t get an error if I change ‘my_general_nonce’ to something else in wp_verify_nonce. It’s as if verify nonce isn’t working?
    Many thanks for any ideas!!

    Reply
  3. I used the BAuth instead of AJAX ….. It worked well i realised my problem was the simple membership plugin that would pre-empt my sessions. So i used this option and it worked like Magic. Thank tou
    $auth = BAuth::get_instance();
    if ($auth->is_logged_in())
    {
    }

    Reply
  4. Thanks . Nice tutorial. By the way when open the page default for (–select user–) it is not showing all the records. However filter is fine.

    Reply

Leave a Comment