WordPress provides a set of great tools for processing ajax requests in plugins (and themes). I’m going to give you a quick example of how these tools can be used to accomplish a variety of tasks. For this example, We’ll just be using some simple alerts, but they will serve very well for demonstration purposes.
The first thing we will do is write our jQuery function. This will be used for interpreting a click event on the front end and sending the request to the server. Name your file ajax-test.js and place it in the root of your plugin folder, or wherever you wish.
1 2 3 4 5 6 7 8 9 10 11 12 13 | jQuery(document).ready( function($) { $(".ajax-link").click( function() { var data = { action: 'test_response', post_var: 'this will be echoed back' }; // the_ajax_script.ajaxurl is a variable that will contain the url to the ajax processing file $.post(the_ajax_script.ajaxurl, data, function(response) { alert(response); }); return false; }); }); |
What we have done in this bit of jQuery is pretty simple. First we run our function anytime that an anchor link with a class of “ajax-link” is clicked. Next, we set up a variable containing the POST variables and their values. Take careful note of our variable names: action, which is set to the value of “test_response”, and post_var, which has a value of “this will be echoed back”. We will use both of these var names in a bit.
Next we use the jQuery $.post() function to send the data variable to the server. Notice the the_ajax_script.ajaxurl parameter. This is a variable containing the url of the ajax processing file. We will set this variable in a little bit. Inside of the post function, we have setup an alert to happen when the request is finished, and we’re going to display the value of the response in our alert(). This will allow us to know if it really worked.
That’s it for the jQuery, so now we move on the PHP.
Inside of your plugin file, or theme file, you need to create two functions: one to load the jquery we just wrote, and one to process the request.
This function will load the JS scripts:
1 2 3 4 5 6 7 8 | function test_ajax_load_scripts() { // load our jquery file that sends the $.post request wp_enqueue_script( "ajax-test", plugin_dir_url( __FILE__ ) . '/ajax-test.js', array( 'jquery' ) ); // make the ajaxurl var available to the above script wp_localize_script( 'ajax-test', 'the_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); } add_action('wp_print_scripts', 'test_ajax_load_scripts'); |
The first part of this function loads and initiates the jQuery file we just wrote. After that, we use wp_localize_script() to send the ajaxurl variable to our script. The first parameter of this function must match the first of the wp_enqueue_script() function.
After we’ve loaded the script and made the ajax url available for use, we make use of add_action() to load the scripts in our site’s header.
Now, we write our last function, which will receive the request sent by our jQuery script, and then send a response back to it. This is where we must remember the var names we used in our data variable in our jQuery.
1 2 3 4 5 6 7 8 9 10 11 | function text_ajax_process_request() { // first check if data is being sent and that it is the data we want if ( isset( $_POST["post_var"] ) ) { // now set our response var equal to that of the POST var (this will need to be sanitized based on what you're doing with with it) $response = $_POST["post_var"]; // send the response back to the front end echo $response; die(); } } add_action('wp_ajax_test_response', 'text_ajax_process_request'); |
This function does little more than check that the correct data is being sent, and then sends the response back. One of the really important things to notice here is the first parameter of the add_action() hook. It has the form of wp_ajax_{action_name} where {action_name} equals the value of the action var we set in our data variable.
Now, if all goes well, you will get a nice alert saying “this will be echoed back” when you click on your link. That’s great because now you can go much farther and beyond this example and utilize this same modal to do some really cool things in your plugins. I recently used this exact technique (and hardly much more code) to write a Mark as Read plugin.
Very nice, looking forward to more useful info
@Jonathan – more coming soon π the last two weeks have been really slow due to the launch of a massive project that has been in the works for a year and a half
Thanks a LOT! Pippin
Just get my Ajax working in fronted Via Plugin ….
& I get this at right time .. I need to learn properly & now I get all form it,
By the way I nice tutorial & code paste here
http://www.itsananderson.com/wcsea.pdf
may be helpful for other like me,…
In the test_ajax_load_scripts() function, plugin_dir_url(__FILE__) includes a trailing slash at the end (according to the Codex). Why would you include a forward slash before the js file name?
plugin_dir_url( __FILE__ ) . ‘/ajax-test.js’
That’s a bug in the code. Thanks for noticing.
Pingback: Drag and Drop Order for Plugin Options | Pippins Plugins
Pingback: Create a Live Search in WordPress with jQuery and Ajax | Pippins Plugins
Can you show how this is implemented on the front end? Where can I put the link? I am using this as a plugin but have no idea where to put the link so that jquery can see it…thanks
I don’t understand your question. Are you asking how to process an ajax request on the front end from your plugin?
Hmm….I think so. Such as I followed the tutorial step by step. The last thing you wrote is “Now, if all goes well, you will get a nice alert saying βthis will be echoed backβ when you click on your link.”
However, where is the link? Basically how can I test it? I have been studying AJAX and WP for a while now and believe I have the basics down. This is the last bit I am trying to understand so that I can build from it.
Do you have this as a complete plugin so that I can download it and look at the source code? Like I said, the part that is messing me up is getting the display link into the front end. I click it and it doesn’t recognize it is AJAX. Same thing happened to me with another tutorial even though I copied it line by line. However when I install your plugin, it works fine. Not sure if the code is different or what..
Thanks!
Got it. I understand your question now. In this case what you need to do is create a link like this:
When you click any link with the class of “ajax-link”, you should trigger the ajax request.
Make sense?
Yes. I couldn’t figure out how to get the link to display, but I took a look at your “love it” plugin and figured it out. It’s all working now. Thanks!!
you should add usage of nonce. Its a builtin feature of wp to add more security.
kind regards
Nonces should only be used in the admin, so if you are doing a front end request there is no need for one.
HI ,
I have try this code . But I got 0 in response . why this happen ?
That usually happens because your security (nonce) check failed. Can you confirm whether it is working or not?
Thanks Pippin … But I’m new in WordPress ….Can you please guide me where to set security (nonce) check ? or How I can solve this issue ?
See here: http://codex.wordpress.org/Wordpress_Nonce_Implementation
Thank you for this!!
I followed your tutorial and got a calendar plugin I’d developed working with an ajax call but now I’m stuck on a few points.
For starters, I’m not sure how to now let users go forward or backward a month. Previously, that could be accomplished with
$html .= ‘Next month‘;
I”m not sure how to pass more than one variable to the ajax call via data ( example: data { month: parseInt(‘2’) } ( but I have month and year…) , or what the correct url is now since we’re relying on admin-axax.php for processing, or if there’s a cache that needs to be cleared once the action has been satisfied — with the calendar, the user should be able to keep incrementing/decrementing the month.
Please forgive me if I’m missing the obvious and thanks very much for any insights/help!!!
Could you show me the code you’re using so I have a little more to go off of?
Hi,
Thanks! I’m trying to figure out how to adapt my code to introduce ajax into the following plugin so that the whole page doesn’t need to reload when the user wants to go forward or backward a month. This plugin is working otherwise.
The calendar only needs two pieces of info: month and year.
Those variables only really need to be introduced to the ‘previous’ and ‘next’ links in bold below, which is why discovering your tutorial was so great for me, that the action was being triggered with a link.
I got your great tutorial working as is. However, if I hit the ajaxurl directly (mysite.com/wp-admin/admin-ajax.php?action=test_response I get a 0. My first challenge is understanding the right way to specify that url. Does it matter that this is a child theme? Then, what the url of the links to move the calendar forward and backward should be. I think I get how to pass the mon and year variables but won’t know until I know what url to specify. My next challenge would be to determine how to structure the functions and their calls. The calendar should load with a get request of today’s date and should move ahead or back with a posted request via the previous and next links… Thanks for any insights and for the great tutorial –
CODE REMOVED.
Please post your code to an external service like snippi.com and then share the link.
This is a good description but really hard to follow. Here’s some questions:
1. Where is the file that does the processing? ie. process.php
2. How do I get that data back to my front-end
3. Why are you displaying an Alert Box as the example? This doesn’t appear to be AJAX to me.
It seems all this example does is show an alert box. Please correct me if I am wrong.
Thanks for the article.
1. It can go in just about any file of your plugin. By utilizing the WordPress wp_ajax_ system, our code doesn’t have to go in a specific file.
2. By echoing the data you want returned inside of the function that is connected to the wp_ajax_YOUR_ACTION hook.
3. It illustrates how you can display an alert when an ajax action is complete.
Really clean explanation Pippin, thanks.
If you have a moment, could you suggest how to load a wordpress post into a element? I would think this would require a nonce as well.
My initial thought would be to replace the post_var with ‘$(this).attr(“id”)’ which would contain the post ID in the link. E.g (post-1).
Then in the process_request() function trim the post_var and execute WP_Query and return the_content() in the response.
Or should you always use the href attribute to load the content?
There are multiple ways to do it, but both methods you mentioned should work fine.
I found with the first method that, no shortcodes would be executed in the_content().
Great write-up Pippen. AJAX confuses me every time I do a new implementation. I’m curious if you have insights into why the response would return the entire document ( not in your example, but in general ). This happened to me once before because I had a redirect for non-logged-in users preventing the admin-ajax from firing. But I have a new case with no active redirects, returning the entire document again. Uber frustrating.
My guess is that you have not included exit; or die(); at the end of the ajax processing function.
Believe it or not, it was an ID on the submit button that caused that. I never would have known that if it weren’t for the fact I reverse engineered my entire plugin by merging it with one that worked. Letter by letter, piece by piece I merged the two and the minute I added the ID to the button, poof, ajax threw up an alert with the raw document HTML.
Ah! That makes sense actually because with an incorrect ID, your function that processes the request will simply be ignored.
Hi Pippin,
Thanks for your post, this is very helpful for everybody. π
I Would like to ask if How can I make a SQL/ $wpdb->insert or $wpdb->update? Am I going to insert the sql inside the text_ajax_process_request() function?
Thanks, Anyway π
John
Yep, just do it inside of the processing function.
Hi Pippin,
How can I pass the variable to the text_ajax_process_request()?
Sorry Im newbie in this field.
Thanks,
John
I’m very new to wordpress development. I was wondering why you have used wp_print_scripts as the action, & then wp_enqueue_script? Why didn’t you use wp_enqueue_scripts as the action? Thank-you. Very helpful tutorial!
They both work in this case. For the purpose of this tutorial, either works fine.
I’m very new to wordpress development. I was wondering why you have used wp_print_scripts as the action, & then wp_enqueue_script? Why didn’t you use wp_enqueue_scripts as the action? Thank-you. Very helpful tutorial!!
Sorry didn’t mean to spam!
This is more of a dumb ques I guess. Sorry if it is.
We could have achieved the same pop-up initially by echoing the response ( which was echoed in text_ajax_process_request) directly by echoing it in first function that we set up in ajax-test.js. If am right, there could be two reasons of why we did this long way –
1. you wanted to show us how to use ajax and jquery combo when situation arises.
2. there was some specific reason using the combo in this particular example.
If it was 1, then what example situation (that you can suggest) could be where we are bound to to use ajax+jquery combo?
if it was 2, what reason was it?
Thanks for the tut.
Do you mean by echoing out the javascript for the popup via the ajax response?
@Pippin: I meant, we can’t produce a popup on a click event directly via jQuery, right? But you chose to show us the ajax method. So what example situation (that you can suggest) could be where we are bound to to use ajax+jquery combo instead of just jQuery?
Sorry I meant to write CAN and wrote CAN’T. Re-framed reply –
@Pippin: I meant, we can produce a popup on a click event directly via jQuery, right? But you chose to show us the ajax method. So what example situation (that you can suggest) could be where we are bound to to use ajax+jquery combo instead of just jQuery?
Here’s a plugin that implements an example of this: http://codecanyon.net/item/user-bookmarks-for-wordpress/544129
It shows a popup notice once the ajax request (to bookmark an item) is successsful.
Is this example outdated for 2014? I slightly modified your example, & posted a problem with it on stack exchange. I’m aware that your example doesn’t validate or sanitize, but I wondered what you thought of the feedback I got from the stack exchange person who answered me. I’m new to coding & wordpress, so slightly confused by the conflicting advice.
Stack exchange person’s answer:
Don’t echo things in the AJAX callback. JavaScript should handle that.
To send data in your callback, use wp_send_json() or the higher level functions wp_send_json_success() and wp_send_json_error(). All of them will die for you. No need to exit or die afterwards.
Data Validation and Sanitization is something you should take serious: $response = $_POST[“post_var”]; is extremely unsafe way to do things. If you already got hacked, then this would have been an open door. Use filter_var() or filter_var_array(), both native PHP functions, or esc_attr() and similar WordPress escaping functions.
AJAX and shortcodes are a very specific thing. Per default AJAX requests go through the admin interface (hence admin-ajax.php as handling route). And shortcodes aren’t needed in the admin UI. They get rendered during runtime when the content of a post gets rendered when looping.
Thank-you for your time!
The wp_send_json_error() is a great function that should definitely be used. It wasn’t used when this tutorial was written because it didn’t exist yet; it was introduced in WP 3.5, after this tutorial was published π
Does the existence of wp_send_json_error() make echoing the data in the ajax callback wrong? Most definitely not.
He is absolutely right about sanitizing the data. I just updated the code to include a note about sanitizing. The exact way the data is sanitized depends largely on what the data is being used for.
For example, if you are taking input from a text field, you may want to use the sanitize_text_field() function. If you are taking a whole number, such as a post ID, you may want to run the post data through absint().
hi i want to call ajax in my plugin in front end.I implemented your way but getting -1 as response!, but when i login as admin then test in front end page then works.
That means you added the “wp_ajax_{your action name” hook but not also the “wp_ajax_nopriv_{your action name}” hook.
Hi pippin,
This is working like a charm. Been looking for this for hours. You saved my day
Cheers.
In the wordpress codex it states that “Since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php”
If I understand this correctly and if my test are accurate you no longer need to use the wp_localize_script to make the admin-ajax.php file available as it is already available by default and you can remove the_ajax_script from the ajax url
http://snippi.com/s/kmj39d5
It’s available in the admin, so you don’t need to do it there, but you still need to on the frontend.
Pingback: Announcing the release of the WP-MP-Contact plugin | Proper Design
This is awesome! I’ve been trying to figure out how to pass back stuff to the php for 2 days now.
Hi
this is not working on firefox and safari for me.
works perfectly on chrome though.
any idea?
the alert returns “0”.
That usually means your action name is incorrect. Make sure the action you pass in your JS matches what you use in add_action( ‘wp_ajax_’ .$action ….);
Awesome…Thanks for posting
Hi Pippin,
How do I get $_POST[“post_var”]; in the template file? Please let me know, It’s urgent.
This is an extremely important analysis on this part of wp. It is the actual article I have looking. Nice touch of technique via the breakdown of the parts.
Keep it up dude.