Wordpress & Web Development

A Tutorial On Using AJAX In WordPress

James Bruce 17-02-2012

ajax tutorialAJAX is a remarkable web technology that moved us beyond the simple “click link, go to another page” structure of The Internet 1.0.


AJAX, which stands for Asynchronous Javascript and XML, enables websites to dynamically fetch and display content without the user moving away from the current page. This leads to a far more interactive user experience, and can speed things up too since a whole new webpage needn’t be loaded. Luckily, making use of AJAX is quite easy to do from within the WordPress environment, and today I’m going to show you how.

This Ajax tutorial should be considered fairly advanced, and continues on from last time where we learnt how to use custom database tables Working With Custom Database Tables In WordPress A quick scan of the Best of WordPress Plugins page will reveal some of the many unique and niche ways you can make your blog work harder. What if you already have a database of... Read More from within a WordPress template – in my example, a simple existing table of customer data was used. When it comes to inserting things back into the database though, we’re going to be making use of a little AJAX magic within WordPress.

All the code in todays tutorial will therefore be referencing what we wrote last time, but if you’re just looking for how to do AJAX in WordPress then it’s equally as relevant.

Why Use AJAX?

The most common use of AJAX is related to forms – checking if a username is taken, or populating the rest of the form with different questions depending on a particular answer you give. Basically though, you use AJAX whenever you want an event (like a user clicking something, or typing something) tied to a server-side action that occurs in the background.

We’re going to use it to add new entries to our important customized customer database table, but you can probably come up with something more exciting.


Overview of How To Use AJAX in WordPress

  1. Edit your custom template to include a form or javascript event that will submit data via jQuery AJAX to admin-ajax.php including whatever post data you want to pass in. Make sure jQuery is being loaded.
  2. Define a function in your theme’s function.php; read post variables, and return something back to the user if you wish.
  3. Add an AJAX action hook for your function.

Creating the Form

Let’s start by creating a simple form on the front-end for entering new customer details. It’s nothing complicated, just replace the main part of your custom template with this code that we began last week, around where the is_user_logged_in() check occurs:

if (is_user_logged_in()):?>

<form type="post" action="" id="newCustomerForm">

<label for="name">Name:</label>
<input name="name" type="text" />

<label for="email">Email:</label>
<input name="email" type="text" />

<label for="phone">Phone:</label>
<input name="phone" type="text" />

<label for="address">Address:</label>
<input name="address" type="text" />

<input type="hidden" name="action" value="addCustomer"/>
<input type="submit">
<div id="feedback"></div>

The only thing that might look odd to you is that there is the use of a hidden input field called action – this contains the name of the function we’ll trigger via AJAX.

ajax tutorial

The PHP Receiver

Next, open up functions.php and add the following line to ensure jQuery is being loaded on your site:


The basic structure for writing an AJAX call is as follows:

function myFunction(){
//do something
add_action('wp_ajax_myFunction', 'myFunction');
add_action('wp_ajax_nopriv_myFunction', 'myFunction');

Those last two lines are action hooks that tell WordPress “I have a function called myFunction, and I want you to listen out for it because it’s going to be called through the AJAX interface” – the first is for admin level users, while wp_ajax_nopriv_ is for users who aren’t logged in. Here’s the complete code for functions.php that we’re going to use to insert data in our special customers table, which I’ll explain shortly:


function addCustomer(){

global $wpdb;

$name = $_POST['name'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$address = $_POST['address'];


echo "Error";

else {
echo "Customer '".$name. "' successfully added, row ID is ".$wpdb->insert_id;

add_action('wp_ajax_addCustomer', 'addCustomer');
add_action('wp_ajax_nopriv_addCustomer', 'addCustomer'); // not really needed

Just as before, we’re declaring the global $wpdb to give us direct access to the database.  We’re then grabbing the POST variables which contain the form data. Surrounded in an IF statement is the function $wpdb->insert, which is what we use to insert data into our table. Since WordPress provides specific functions for inserting regular posts and meta data, this $wpdb->insert method is generally only used for custom tables. You can read more about it on the Codex, but basically it takes the name of the table to be inserted into, followed by an array of column/value pairs.

The ===FALSE checks to see if the insert function failed, and if so, it outputs “error“. If not, we’re just sending a message to the user that Customer X was added, and echoing the $wpdb->insert_id variable, which indicates the auto-increment variable of the last insert operation that happened (assuming you’ve set a field that auto-increments, like an ID).


Finally, die() will override the default die(0) provided by WordPress – this isn’t essential as such, but without it you’re going to get 0 appended to the end of anything you send back to the template.

The Javascript

The final step is the magic bit – the actual Javascript that will initiate the AJAX call. You’ll notice that in the form we added earlier, the action field was left blank. That’s because we’ll be overriding this with our AJAX call. The general way to do this would be:



url: "/wp-admin/admin-ajax.php", // our PHP handler file

data: "myDataString",


// do something with returned data



That’s the basic structure of AJAX call we’ll be using, but certainly not the only way you can do it. You might be wondering why we’re referring to wp-admin here, even though this will be on the front-end of the site. This is just where the AJAX handler resides, whether you’re using it for front or admin side functions – confusing, I know. Paste the following code directly into the customer template:

<script type="text/javascript">

function ajaxSubmit(){

var newCustomerForm = jQuery(this).serialize();

url: "/wp-admin/admin-ajax.php",
data: newCustomerForm,

return false;

In the first line, we’re attaching our ajaxSubmit function to the form we made earlier – so when the user clicks submit, it goes via our special AJAX function. Without this, our form will do nothing. In our ajaxSubmit() function, the first thing we do is to serialize() the form. This just takes all the form values, and turns them into one long string that our PHP will parse out later. If it all works out right, we’ll put the returned data into the DIV with the id of feedback.


That’s it. Save everything, refresh and try submitting some form data. If you’re having problems, you can view the full code of the page template here (based on the default twenty-eleven theme), and the code to add to functions.php here (don’t replace, just add this on the end).

ajax tutorial

Things to Keep In Mind

Security: This code isn’t production ready and is for the purposes of learning only. We have left out one key point, and that’s the use of a wp-nonce – a one-off code generated by WordPress that ensures the AJAX request is only coming from where it was intended; a passkey if you will. Without that, your function could effectively be exploited to insert random data. SQL injection attacks aren’t a problem though, because we routed queries through the WordPress $wpdb->insert function – WordPress cleans any inputs for you and makes them safe.

Updating the table of customers: Right now, we only send back a confirmation message, but the table of customers doesn’t get updated – you’ll only see the additional entries if you refresh the page (which kind of defeats the purpose of doing this all via AJAX). See if you can make a new AJAX function that can dynamically output the table.

Input Validation: because there’s no validation going on with the form data, it’s actually possible to add blank entries, or multiple entries if you press too many times. Some input validation on the form fields, clearing them when completed, as well SQL to check the email or phone number that doesn’t already exist in the database would be useful.

That’s it from me this week – if you’ve had any problems following this tutorial then feel free to get in touch via the comments and I’ll do my best to help you; or if you’re trying to customize this in some way, feel free to bounce ideas off me. I hope this really goes to show just how much you can do from within WordPress simply by combining a little JavaScript, PHP, and MySQL. As ever, don’t forget to check out all our other WordPress articles.

Related topics: Programming, Webmaster Tools, Wordpress.

Affiliate Disclosure: By buying the products we recommend, you help keep the site alive. Read more.

Whatsapp Pinterest

Leave a Reply

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

  1. Taofeek Folami
    May 18, 2018 at 5:10 pm

    Although, this example is about 6 years old, i cant seem to get it to work. The problem is withing the addCustomer function.
    I am developing locally, i.e. on localhost, WAMP , Wordpres 4.9.5, PHP 7.0.23, Apache 2.4.27. The addCustomer function in that form does not work. It gives "localhost object object " error. It requires if isset($_POST['action']) to remove that error. However, the IF isset() never resolves to true. We did a vardump of the post data and it had all the data. All approaches i made hve not worked.
    Change submit button to button type and change use the .click() method instead of submit. Your thoughts will be appreciated.

    • James Bruce
      May 21, 2018 at 8:05 am

      Is that error being sent back to the feedback field via PHP, or is it in the javascript console? Do you have a database table for customers added already?

  2. Alex
    July 29, 2017 at 6:00 pm

    How can you pass the function name in an alternative way?

  3. alpesh
    March 1, 2017 at 11:35 am


  4. Divyesh
    December 27, 2016 at 11:05 am

    Hi..I will try above code for my custom template..
    But few things Email was not save on database before login wordpress admin.
    So,please give me the reason behind this...
    Divyesh Kakrecha.

  5. Divyesh Kakarecha
    December 23, 2016 at 7:33 am

    Hi I will apply Above code in my custom template.but,It will not work on Mozilla firefox window.
    Please help me appropriates.

  6. Alex
    November 15, 2016 at 9:04 am

    The article on digital apps covers nonce if anybody is interested securing their script


  7. Navas Fazil
    October 7, 2016 at 5:04 am


    could you help me to get the whole file of above example.


  8. Mehul
    July 7, 2016 at 6:10 am

    i want to use dependant drop down in wordpress using ajax

  9. hitesh
    July 6, 2016 at 5:45 pm

    Hi I want to learn how to ajax code use in wordpress theme to click on menu on post(body) part reload. please help me step by step.

  10. rakesh kumar
    May 8, 2016 at 3:19 pm

    This is one of the simplest ajax tutorial on WordPress and I am going to use this method in my new Tour Operator WordPress theme. Thanks a ton for this wonderful article.

  11. Guilherme
    April 20, 2016 at 2:43 pm

    Very nice post!

  12. Prob
    April 15, 2016 at 6:48 am

    HOw to load processing .gif while submitting form ?

    • James Bruce
      April 15, 2016 at 7:27 am

      Look up jQuery for targetting elements, find the submit button or create a span after it, then use the innerHTML method to insert the img tag pointing to the gif. Insert it just before the actual AJAX function is called, and on success, remove the img again.

      • Prob
        April 15, 2016 at 8:03 am

        Hi , thnx for the reply, I used ajaxStart and ajaxStop function to show and hide the .gif image.. Like this:


        it's working !! thnx for the great tutorial

  13. Shafiq Tahir
    April 11, 2016 at 1:24 pm

    I can't get any data in wp nonce field in ajax form submittion.

  14. Neyo Boy
    March 30, 2016 at 9:44 am

    awesome tutorial. thxn

  15. im anonimous
    March 19, 2016 at 8:20 pm

    Thanks a lot. this tutorial well explained how to use ajax calls in wordpress. i was searching for many posts in the internet but this was the best which well explained the thoory and codings. solved my problem also

  16. Praval
    February 13, 2016 at 11:30 pm

    I would say it explained it so well.. it solved all my problems :) Thanks a ton :) I have not tried anything, but now I know exactly what I need to do :) this is what many other tutorials are missing, a simple explanation of why they are doing whatever they are doing, and here its done really very properly and that helps.. :)

  17. Martin
    January 19, 2016 at 3:01 pm

    Hi, is it possible to work with update_user_meta as well? Thanks and best regards

  18. Brenton
    January 12, 2016 at 12:23 pm

    Good afternoon, I have managed to sort out my problem

  19. Brenton
    January 12, 2016 at 1:35 am

    Hi, I have created a form that has to be redirected to a thirdparty site. I have used ajax to update my database and would now like to set the id as a viriable on my form. Where you have,
    echo "Customer '".$name. "' successfully added, row ID is ".$wpdb->insert_id; I have created,
    $Reference = $wpdb->insert_id;
    echo $Reference; which echos the id on the . Instead of just echoing this id I would actually like to set it as a variable on the form so that it can be used in a calculation before I submit the form.

  20. dave
    January 2, 2016 at 9:10 am

    hi james bruce, i need a little help. can you please give me your email address (you can send me yours to dave.shoaib3@gmail.com. i can send the details separately. i can pay for your help.


  21. dave shoaib
    December 5, 2015 at 2:03 pm

    sorry i can't see my msg here but i received your reply and just want to say thanks for your very fast reply. regards..

  22. dave shoaib
    December 5, 2015 at 1:33 pm

    hi james, thanks for your wonderful writeup.
    a question here: i am trying to use a plugin to create a form for submission. how should i replace just the form part of your code with the form created by the plugin. i guess we can keep javascript and functions parts as they are. just the form part i want to make use of a plugin.
    thanks for your help.

    • James Bruce
      December 5, 2015 at 1:44 pm

      I would guess you just use the plugin to make the form you want, then copy the HTML it produces and replace what's above. You just need to change the ID of the form to be the same as that referenced in the script - jQuery('#newCustomerForm').submit(ajaxSubmit);

  23. Anonymous
    June 29, 2015 at 9:06 pm

    your inline coding method is super annoying to read...why cant you have block text? instead of scrolling all the way to infinity -_-

    • James Bruce
      June 29, 2015 at 9:12 pm

      We do nowadays. This was written 3 years ago. And really, it was designed to just copy and paste.

      • Anonymous
        June 29, 2015 at 9:51 pm

        Ok thanks, although copy and paste just pastes everything in one line. But still, thanks! cuz I got it to work :)

  24. juan
    May 18, 2015 at 12:25 am

    Esta bien el post

  25. juan
    May 18, 2015 at 12:24 am

    Esta bueno el articulo

  26. Daniel
    April 11, 2015 at 4:27 am

    For anyone running their WordPress installation from a folder on their server, make sure your AJAX submit URL looks like this:
    url: "/wp-admin/admin-ajax.php",

    ...this will save you so much time!

    • Daniel
      April 11, 2015 at 4:29 am

      That's supposed to be " /wp-admin/admin-ajax.php"
      (without the commas) It got removed from my post...

    • Daniel
      April 11, 2015 at 4:30 am

      Got removed again...
      php bloginfo('wpurl'); /wp-admin/admin-ajax.php

  27. saniul
    February 9, 2015 at 9:06 am

    url: “../wp-admin/admin-ajax.php”
    this will work... if you are submitting from front end.

  28. Alex
    May 30, 2012 at 6:15 pm

    The ajaxurl is not available on the front-end by default: http://codex.wordpress.org/AJAX_in_Plugins
    [Broken URL Removed]

  29. Alex
    May 30, 2012 at 1:00 pm

    You should always separate the javascript from the HTML output. The javascript should live in its own file and be enqueued to the header.

    • muotechguy
      May 30, 2012 at 1:05 pm

      I respectfully disagree. What if you have PHP dependant Javascript variables? WordPress doesn't have a Javascript API, so you're left with declaring Javascript globals somewhere in the PHP regardless.

      On a single page template, it also keeps things neater and more efficient. Theres simply no need to make multiple files and hook into the header.

  30. Sharaz
    May 18, 2012 at 5:43 am

    I tried you tutorial but I don't think data is getting to my PHP function. I get a returned value of 0. Any ideas?

    • Camaleo
      June 25, 2012 at 8:44 am

      @Sharaz I had the same problem when I used uppercase letters in the first add_action parameter:

      the following return "0" :(

      add_action('wp_ajax_form_Test_Validator', '__formTestValidator');
      add_action('wp_ajax_form_Test_Validator', '__formTestValidator');

      the following work :)
      add_action('wp_ajax_form_test_validator', '__formTestValidator');
      add_action('wp_ajax_form_test_validator', '__formTestValidator');

      @James Simple, clean... perfect: Thank you so much!!

      • muotechguy
        June 25, 2012 at 8:57 am

        Are you running on Windows server by any chance? Or perhaps an older version of PHP?

        • Camaleo
          June 25, 2012 at 9:29 am

          I am on OSX 10.7.4, MAMP PRO, PHP 5.2.17

        • muotechguy
          June 25, 2012 at 9:30 am

          Ahh, probably the local server thing is not liking the capitalisation. Oh well, as long as you got it fixed, thanks adding that for others here.

      • Camaleo
        June 25, 2012 at 9:27 am

        sorry Sharaz, I meant:

        add_action(‘wp_ajax_form_Test_Validator’, ‘__formTestValidator’);
        add_action(‘wp_ajax_nopriv_form_test_validator’, ‘__formTestValidator’);

        add_action(‘wp_ajax_form_test_validator’, ‘__formTestValidator’);
        add_action(‘wp_ajax_nopriv_form_test_validator’, ‘__formTestValidator’);

        also, if you keep seeing a 0 in the ajax output, be sure to close function addCustomer() with a die(); I guess using a return; will let ajax print the result code.

  31. Edgar
    March 30, 2012 at 1:32 pm

    Very helpful post. I did the same process that you mention but when I sutdmit the form I receive an error saying "[object Object]". Do you have an idea of what I am doing wrong?

    • muotechguy
      March 30, 2012 at 1:40 pm

      Can you post a URL for me to test from? The debugger should show me what exactly the object being returned is.

      • Edgar
        March 30, 2012 at 1:57 pm

        Hey!! Thank You for your response! I used the debugger I found the issue. My theme and this were loading different jquery versions.

    • Anthony
      April 24, 2012 at 6:57 pm

      your example working corectly in localhost but when I tried it on domain Ajax return -1 The same situtaion is in localhost in Chrome browser. Path to ajax is correct. thank you for you support

      • muotechguy
        April 25, 2012 at 8:24 am

        Could you post a URL?

        • Anthony
          April 25, 2012 at 2:44 pm

          Yes URL is correct problem in admin-ajax.php line48 die('-1'); I tried return jQuery.post("", { name: "John", time: "2pm" } ); to existing site URL but still error 404 have you any idea why. page exist it is not problem. What I doing? I create new custom post typy wp_insert_post( $tacher_cal_post, $wp_error );
          Working correctly but I need return $post_id to $_POST variable for the next post processing in template file.

        • muotechguy
          April 26, 2012 at 7:43 am

          I mean, please post a URL for a demo page, and a pastebin with relevant code added if you can. It's difficult to tell you whats wrong with the code you've pasted here...