Use AJAX with WordPress in 3 ways

Here we will see the use of AJAX to get data using 3 most used tools.

Server Side Code

Let’s start by creating function and two hooks in your functions.php file in root of your active theme folder. The name of the function will be used in client side to make a network request, that’s how WordPress identifies which function needs to be executed because all requests are made to same url.

WordPress gives two hooks with suffix of our custom function name of choice. To make it simple, we will call it “get_recent_posts_ajax”. One hook is for logged in users and other is for guest users. Here we are just returning a JSON response, but you do any complex calculations here or make another network request with cURL.

function get_recent_posts_ajax(){
    if( !wp_verify_nonce($_POST['nounce'],'get_recent_posts_ajax') ){
        echo json_encode(array( 'status' => false, 'message' => 'Nounce error' ));
        exit(0);
    }

    $data = array();
    $posts = wp_get_recent_posts(array(
        'posts_per_page' => $_POST['number_of_posts'],
        'post_status' => 'publish',
    ));

    foreach ($posts as $key => $value) {
        $data[] = array(
            'ID' => $value['ID'],
            'post_date' => $value['post_date'],
            'post_title' => $value['post_title'],
            'post_excerpt' => $value['post_excerpt'],
            'comment_count' => $value['comment_count'],
            'permalink' => get_permalink($value['ID']),
        );
    }
    echo json_encode($data);
    exit(0);
}
// For logged in users
add_action('wp_ajax_get_recent_posts_ajax', 'get_recent_posts_ajax');
// For not logged in users
add_action('wp_ajax_no_priv_get_recent_posts_ajax', 'get_recent_posts_ajax');

Client side

Here most of the code is self-explanatory and consider this is more like a code snippet, not a detailed explanation.

HTML

To begin with, we will create a basic form with simple text fields. We will also include a hidden field named “action” and give it value. We used the function at server side with the same name as this value so don’t use any hypen in it.

<form id="form" action="<?php echo admin_url('admin-ajax.php'); ?>">
    <input type="number" min="1" name="number_of_posts" value="" required />
    <input type="hidden" name="nounce" value="<?php echo wp_create_nonce('get_recent_posts_ajax'); ?>" />
    <input type="hidden" name="action" value="get_recent_posts_ajax" />
    <button type="submit">Submit</button>
</form>

Option 1: Vanilla JS

var form = document.getElementById('form');
form.addEventListener('submit', function(e){
    e.preventDefault();

    var formData = new FormData(form);
    formData.append('extra_key', 'extra_value');
    var xhr = new XMLHttpRequest();
    xhr.open('POST', form.getAttribute('action'), true);
    xhr.onreadystatechange = function (res) {
        if (this.readyState == 4 && this.status == 200) {
            var res = JSON.parse(xhr.responseText);
            console.log(res);
        }
        if (this.readyState == 4 && this.status == 404){
            console.log('An error occurred')
        }
    }
    xhr.send(formData);

}, false);

Option 2: Axios

var form = document.getElementById('form');
form.addEventListener('submit', function(e){
    e.preventDefault();

    var formData = new FormData(form);
    formData.append('extra_key', 'extra_value');
    var xhr = new XMLHttpRequest();
    axios.post(form.getAttribute('action'),
        formData
    ).then(function (res) {
        console.log(res.data);
    }).catch(function (err) {
        console.log(err);
    }).then(function () {
        // always executed
    });

}, false);

Option 3: jQuery

jQuery(function ($) {

    $('#form').on('submit', function(e){
        e.preventDefault(); // prevent page refresh on submit

        var formData = new FormData($('#form')[0]); // pass HTML form element as argument
        formData.append('extra_key', 'extra_value');
        $.ajax({
            method: 'POST',
            data: $('#form').serialize(), // you can also use jQuery serialize
            // data: formData,
            // processData: false, // add this if using "new FormData"
            // contentType: false, // add this if using "new FormData"
            url: $('#form').attr('action'),
        }).done(function(res) {
            var res = $.parseJSON(res)
            console.log(res);
        }).fail(function(err){
            console.log(err);
        }).always(function(){
            console.log('this will always execute');
        });
    });

});