An ajax demo for WordPress, with debugging tips, to show that it is not so hard. Includes code you can download and quickly use.
When you start to write some ajax code for WordPress it can be intimidating because there are a number of strings in your PHP and Javascript code that need to be in sync. Once you have that sorted them you are well on your way.
To show these strings I am going to present a simple demo. It has two buttons that will return the number of posts and pages on the current blog.
I have written it as a plugin so that it can be easily activated and deactivated and it is not dependant on editing any theme files.
Result
Here is what we will be producing. When you click the ‘Get Post Count‘ button it will display the number of posts on this blog underneath itself. Try it out:
Post Count: 383
Page Count: 14
Use a Shortcode for Easy Setup
For this demo I will use a shortcode to create the buttons that will start the ajax calls. This makes it easier to set up the buttons.
The buttons have a common CSS class (that will be used in the Javascript). They also have a ‘data-type‘ attribute with a value that corresponds to the post type that we will be getting a count of. Finally, there is a ‘div‘ with an id that matches post type (e.g. id=”post_count”). Again, this will be used in the Javascript.
To confirm that the ajax code is returning the correct values the post and page counts are included in the shortcode output.
Include the Javascript File
Next up is to enqueue the Javascript file. Here we have the first two strings that need to be in sync.
The Javascript file, which must be in the same directory as the plugin code, is given a ‘handle‘ name (‘aj-demo‘ here). The wp_enqueue_script() call will generate html code like:
The Javascript code needs to know how to communicate with WordPress so we need to set the path to the admin-ajax.php script. We do this via the wp_localize_script() function. We also include a nonce value here, to help secure the ajax query (we will verify it in the ajax handler). You may also include additional variables here. These can be referenced in the Javscript code to make decisions there or to pass to the ajax PHP code.
This will generate html code like:
To make the demo even simpler it would have preferable not to need the external Javascript file but, wp_localize_script() would not work without one.
Write the Ajax Handler
The function is short and simple.
The first parameter of the add_action() call (‘wp_ajax_nopriv_aj_ajax_demo_get_count‘ and ‘wp_ajax_aj_ajax_demo_get_count‘) includes a string that is used in the Javascript file – ‘aj_ajax_demo_get_count‘. When the ajax call is made from the Javascript code WordPress knows the function that will handle it – ‘aj_ajax_demo_process‘. The ‘nopriv‘ version is for users that are not logged in. You may choose to have two different functions handle the ajax call or maybe only handle it for logged in users. For this demo the answer will be the same for both.
First step is to check the nonce. The ‘aj-demo-nonce‘ string was passed to ‘wp_localize_script()‘. If the check fails then the function will die – there isn’t any need to check its return value.
Even if the nonce is correct we need to check the incoming data. We use ‘sanitize_text_field()‘ which will strip out tags and other harmful characters. Then we check that the post type is a valid one before getting a count of published posts of that type.
Write the Ajax Javascript Code
Create a file called aj-demo-ajax-code.js.
This code probably looks more complicated than it is. Let me break it down.
The code runs when an element with a class of ‘count_btn‘ is clicked (this will be one of the two buttons generated by the shortcode).
To reduce the amount of Javascript code we use a class instead of an id. Unfortunately we now don’t know which button was pressed – the posts button or the pages button. This is where the ‘data-type‘ attribute comes in. It has a value of ‘post‘ or ‘page‘.
The code then clears the existing value, by setting the text to a question mark. This will visually demonstrate that the ajax code is running.
The e.preventDefault() call tells the element not do its default behaviour. This is not an issue here but would be for a link element or form submit button.
Now we can set up the ajax call.
For the ‘url‘ we are referencing the ‘aj_ajax_demo‘ string that was used in the wp_localize_script() call.
The ‘type‘ is not the post type we are querying but how the ajax call will be submitted – it could be ‘get‘ but that is rarely used.
The ‘nonce‘ also references the ‘aj_ajax_demo‘ string.
The ‘post_type‘ is from the ‘data-type‘ query earlier.
The ‘aj_ajax_demo_get_count‘ is used in the ‘add_action()‘ call in the ajax handler code above.
This is enough to run the ajax call.
When the call returns then the returned value is put in the appropriate div.
If your code returns a data structure then you will have to parse it before using it.
Debugging
Debugging ajax code is even harder than debugging regular WordPress code because you cannot easily generate debug messages within the data that the ajax code returns.
I recommend developing ajax code in two steps – firstly develop the ajax handler code. If the code is complex, then writing a standalone WordPress script will be a great help. You can write the code and it is easy to include debug messages in the output.
When it comes to the Javascript portion you should enable WordPress debug mode and add some error_log() calls to the ajax hander, primarily to ensure that the handler is being run. Earlier debugging with a standalone WordPress script should ensure that the rest of the handler will run without issues (or with minimal issues).
In the Javascript code you can add a few alert() calls to verify how far the code gets and a few console.log() calls to see the data being passed around.
Strings to be in Sync
The ajax code is made up of three sections of code – enqueue & localize the Javascript file, the Javascript file and the ajax handler. Each has dependencies on another section.
Enqueue/Localize and the Javascript File
Firstly an internal dependency: the first parameter of wp_enqueue_script() and wp_localize_script() must match. In this demo it is ‘aj-demo‘
wp_enqueue_script( 'aj-demo', plugin_dir_url( __FILE__ ). 'aj-demo-ajax-code.js', array('jquery') ); // The second parameter ('aj_ajax_url') will be used in the javascript code. wp_localize_script( 'aj-demo', 'aj_ajax_demo', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'aj_demo_nonce' => wp_create_nonce('aj-demo-nonce') ));
Localize and the Javascript File
Then the second parameter of wp_localize_script() (‘aj_ajax_demo‘ here) is the prefix in the Javascript code to access the passed variables.
wp_localize_script( 'aj-demo', 'aj_ajax_demo', array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'aj_demo_nonce' => wp_create_nonce('aj-demo-nonce') ));
jQuery.ajax({ url : aj_ajax_demo.ajax_url, // Note that 'aj_ajax_demo' is from the wp_localize_script() call. type : 'post', data : { action : 'aj_ajax_demo_get_count', // Note that this is part of the add_action() call. nonce : aj_ajax_demo.aj_demo_nonce, // Note that 'aj_demo_nonce' is from the wp_localize_script() call. post_type : post_type }
Javascript action and Ajax Handler
Finally the ‘action‘ parameter of the jQuery.ajax() call must match the add_action() code that sets up the ajax handler.
jQuery.ajax({ url : aj_ajax_demo.ajax_url, // Note that 'aj_ajax_demo' is from the wp_localize_script() call. type : 'post', data : { action : 'aj_ajax_demo_get_count', // Note that this is part of the add_action() call. nonce : aj_ajax_demo.aj_demo_nonce, // Note that 'aj_demo_nonce' is from the wp_localize_script() call. post_type : post_type },
// Note that 'aj_ajax_demo_get_count' in the first parameter is the 'action' value in the JS file. add_action( 'wp_ajax_nopriv_aj_ajax_demo_get_count', 'aj_ajax_demo_process' ); add_action( 'wp_ajax_aj_ajax_demo_get_count', 'aj_ajax_demo_process' ); // For logged in users.
Finishing
I hope that this has been helpful and has made ajax code less intimidating.
Maybe GenerateWP will produce a generator to write skeleton code for ajax.
Full Plugin Code
Here is the full PHP code if you would like to try it out on your own site.
You also need the aj-demo-ajax-code.js file.
The js and php files need to be in the same directory. I have zipped the two files together. You can upload this file with the ‘Upload Plugin‘ button on your ‘Plugins/Add New‘ page.
Download aj-demo.zip plugin
this is not working
@Sebastopolys: Thank you for reporting that the code didn’t work. I found that I had mistake in the PHP code – it was trying to load ‘dc-ajax-demo.js’ but the file is called ‘aj-demo-ajax-code.js’. I have fixed the code. I also changed the post where it also mentioned ‘dc-ajax-demo.js’ – it now says ‘aj-demo-ajax-code.js’.
Furthermore, I have zipped the JS and PHP file together into a zip file that can be easily uploaded to your website. I added a download link to the bottom of the post. https://www.damiencarbery.com/wp-content/uploads/2017/02/aj-demo.zip
I hope that this helps you. Please let me know if it now works for you.
Great. Now yes it’s working But I am not using your code, just studying all codes I found since I am learning AJAX ,. I need to do a AJAX call in mi plugin, but can’t figure out how to achieve mi goal-.
can you help me please?
Could you start with my code and then slowly change it to the code you want? Can you post your code to pastebin.com so that I can have a look at it?
its not working anymore, im getting “Error retrieving the information: 403 Forbidden”
When did the code work? Has something changed on your site e.g. password protection? The demo code in this post works so I hope that the solution is something simple at your end.
I emailed Rusty. It’s working again without code changes.
Thanks Damien for sharing this, It works like a charm on my site and help me to start working with Ajax on WP !