Intro
I’m used to working with WordPress a lot and manipulating posts and custom fields and what not.I can query the database for certain info and change info based on submitted info… Lots of info stuff going on. But I usually do so after a nice page refresh.
Normally someone enters data into a form. They press submit, the page reloads and during that time, I have managed to take the input data and create a post, or change one, or make an entry or somehow add something to my DB.
But I’ve never really dabbled with AJAX as I never really needed it yet. AJAX is the ability to pull or push info to the server without the page having to reload. It stand for ‘Asynchronous JavaScript And XML’.
I guess they needed the A for ‘And’… AJX doesn’t sound as cool.
Well anyways AJAX allows us to send and receive data without reloading the page. This means we can do some JavaScript and send some info to the server where we can allow php to take over and do whatever we need to do. Then we can send back some info via JavaScript.
I recently needed to create a site where a special post’s meta was being gotten and output on the front. Then with a click it would check to see if there was a change and output it if there was. This was to be done without a refresh of the page. Here is how I did it.
First let’s go through all the steps needed:
- We need to create a javascript file where we will put our javascript AJAX code.
- We need to pass some php variables to be used in this file.
- We run the ajax code and d some front end stuff
- We then need to pass that AJAX code back to the server where php will be processed.
- Then php will pass some data back to the front end.
- We will use javascript to output the data we get back.
It can be confusing because you need to make code in two separate files: one in php and one in javascript. But hopefully this will help.
Creating the javascript file
To start with, we need to create a javascript file and have it called in on the front end. We’ll do this by using php, and the WP function wp_enqueue_script()
.
We also need to pass some info to this new javascript file to work with. I will be passing 2 variables to use in this file. This is done by using wp_localize_script()
.
Here you can read more about these:
Altogether, this allows us to add our javascript file, and inside the javascript file, I can use the variables (ajaxurl and nonce) I create. Here it is altogether:
function my_scripts(){
//file where AJAX code will be found
wp_enqueue_script( 'my-script-handle', get_template_directory_uri() . '/js/my_script_file.js', array('jquery'), true );
//passing variables to the javascript file
wp_localize_script('my-script-handle', 'frontEndAjax', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce('ajax_nonce')
));
}
add_action( 'wp_enqueue_scripts', 'my_scripts' );
So, here in functions.php I am adding this snippet which will enqueue my javascript file. My js file has a handle called my-script-handle. You can name it whatever you want. I also made sure jQuery is loaded before this file gets loaded because I will be using jQuery to do the AJAX stuff.
Localizing the variable to use in my javascript file
I then use the localizing script which allows me to pass variables from php to the javascript file with the same handle name. Make sure you use the same handle name for the localized script as your javascript file. This will allow you to use those variables in the new file when the file is loaded. Here I created two variables to use:
- frontEndAjax.ajaxurl
- frontEndAjax.nonce
Once we write our AJAX code we need to send it somewhere. Sending it to a random php file we create would work, but we wont be able to use any of WordPress’s functions. We need to send it to a file that loads the WordPress core so that we can do WordPress stuff, like query for a post or some custom meta.
This ‘ajaxurl’ is a special php file that WordPress has that allows you to pass ajax back to the server while using WordPress functions. We will send our ajax code to this file so that it can be processed properly. That file in turn will load all of WordPress, including our themes functions.php file. This means we can add code in our functions.php file to be used for AJAX.
The nonce is a safety feature to stop certain kind of (replay) attacks and makes sure that the ajax (I cant keep spelling it with capitals ok!) code coming to the server originates from your site. You can look up more about nonce with google. We will simply pass the nonce to the javascript code and then send it back and if it matches, then its good, otherwise we wont allow it to run our code.
Both these variables need to be created on the php side. The nonce cannot be created on the front end. And the admin ajax url is also easily gotten on the php side in WordPress. So I needed to do that now. Later I will be able to access them in the javascript file as variables.
Writing the AJAX code in the js file
Now we have the file being loaded properly. If you didn’t create it yet, go and create the file now. Make sure it matches the path we chose in the code above. In my case, and probably yours, you have a ‘js’ folder in your themes directory. Put it there.
Now open the file and we can begin adding our ajax code! I would give you the code slowly in chunks and then tell you what each part does, but whenever I read tutorials that do this, its kind of annoying. I think it’s better to just give you the whole thing and then explain. 🙂
//run code only after the whole page is loaded
jQuery(document).ready( function($){
//when the button is clicked run the ajax function
$('#do-ajax').on('click', runMyAjax);
function runMyAjax(){
var $somedata = $('#my-ajax-item').val();
var data = {
'action': 'my_ajax_function', //the function in php functions to call
'data_to_pass': $somedata,
'nonce': frontEndAjax.nonce
};
//send data to the php file admin-ajax which was stored in the variable ajaxurl
$.post(frontEndAjax.ajaxurl, data, function( response ) {
//simple test. if new string brought back doesn't match old string.
if(response.data_from_backend !== $somedata){
$('#my-ajax-item').val(response.data_from_backend);
}
}, 'json' );
} //end runMyAjax
//end document ready
});
Here using jQuery we tell the page to wait till the whole page has been loaded. Then I made a simple click event that calls my ajax function. Assuming I have a button with an ID of ‘#do-ajax’. When it is clicked I will get the value of some item on the page. Perhaps a textarea. I dunno I’m making it up as I go along… Then we will send that value to the backend for some processing.
The mandatory fields
I created my data in json notation. You can pass whatever data you want back, but two objects will be mandatory when working with WordPress:
- action
- nonce
This data will be sent to the admin-ajax url I spoke of earlier. The admin-ajax php will run and look for the action and get its value. It will then know to run a function called by that value. In this case I passed the value ‘my_ajax_function’. So I will need to make a php function by the same name. We will get to that soon.
We will also send the nonce variable inside the ‘nonce’ object. This was created with the localized script. This way we can check and make sure it matches on both sides, front-end and back-end.
With the data in place its time to actually send it to the back-end. So using jQuery’s post function we send the data. The data is sent to the ajaxurl variable we had created with the localized script function. As stated before, this allows us to use WordPress when working with the AJAX code.
Your own data to pass
Like I said, you can pass any data. So I passed ‘data_to_pass’, some random textarea’s string value from an item on the page called #my_ajax_item. I then send this off to let php take care of it.
On the php end I will check the nonce. If it passes then I will send back some new string. I will replace the old string if the string that’s there doesn’t match. Just a simple test case to show you what sort of stuff you can do here.
The php side
Time to make the my_ajax_function that will take the data we send. Open functions.php and make a function named after the value you put in ‘action’ in the js file. Here is my function:
function my_ajax_function(){
//checking the nonce. will die if it is no good.
check_ajax_referer('ajax_nonce', 'nonce');
//now we can get the data we passed via $_POST[]. make sure it isn't empty first.
if(! empty( $_POST['data_to_pass'] ) ){
$my_paragraphs_text = esc_html($_POST['data_to_pass']);
}
//if the textarea equals a certain value we will send back a different string
if($my_paragraphs_text == 'saltnpixels is so cool'){
$ajax_response = array('data_from_backend' => 'yes it is!!');
}
else{
$ajax_response = array('data_from_backend' => "These are not the droids you're looking for…");
}
echo json_encode( $ajax_response ); //always echo an array encoded in json
die();
}
add_action( 'wp_ajax_nopriv_my_ajax_function', 'my_ajax_function' );
add_action( 'wp_ajax_my_ajax_function', 'my_ajax_function' );
Here I have created a simple function. I first check the nonce using this function WordPress has. check_ajax_referer()
which takes the name of the nonce we created all the way in the beginning plus the name of the data where it was stored on the front end, which would be $_POST[‘nonce’]. But WordPress just needs the name so just pass ‘nonce’.
Now we can play with the data we passed back! Here I am checking to see if the value of the text area exists. If it does I check if it has a special string value. If so, I send back a new special value. Otherwise I send something else.
Always make sure to send back an array by echoing it. Also make sure to encode it in json, as that is what our ajax function expects back. And also make sure to end with die(). It sounds sad but we must stop the php as it is no longer needed.
Hooking our function into AJAX
Adding the ajax actions is the last step. It will hook our functions in so that when the WordPress admin-ajax file gets the ajax code, it can route it to our function, which has a name set in the ‘action’ object we created in the ajax phase.
As you can see we need two actions. The difference is the word ‘nopriv’. This is the same hook as the one below it, except this will even allow logged out users to access the ajax function.
You may or may not need both for your purposes. Here I used both because I want everyone to be able to use this.
Demo
I guess I should walk the walk and not just talk the talk huh 🙂
Ok. Here let’s make a textarea, Let’s see if it works. I’ll make a textarea and a button.
Demo
Write something below. Write ‘saltnpixels is so cool’, to get the special response.
It Works! Super! Well that’s how you can add ajax to your WordPress site.
Polling
Sometimes you want the ajax to run on a cycle checking for new stuff every 15 to 20 seconds without having to click anything. For this you can do something like this:
jQuery(document).ready( function($){
//run the function right away instead of using a click event
runMyAjax();
function runMyAjax(){
var $somedata = $('#my-ajax-item').val();
var data = {
'action': 'my_ajax_function', //the function in php functions to call
'data_to_pass': $somedata,
'nonce': frontEndAjax.nonce
};
//send data to the php file admin-ajax which was stored in the variable ajaxurl
$.post(frontEndAjax.ajaxurl, data, function( response ) {
//simple test. if new string brought back doesn't match old string.
if(response.data_from_backend !== $somedata){
$('#my-ajax-item').val(response.data_from_backend);
}
// Wait 15 seconds, and run the function again
setTimeout( runMyAjax, 15000 );
}, 'json' );
} //end runMyAjax
//end document ready
});
The changes made here are that I took away the click event and instead ran my ajax function right away. Then inside the function I tell it to run it again every 15 seconds. So it will check for changes every 15 seconds.
And that’s pretty much how I use ajax.
I know there is something called WP Heartbeat… I haven’t touched it yet but it is similar to the ajax polling here except it uses a built-in WordPress ajax polling that already exists. Perhaps I will play with that soon!
incorect
i used form.serialize() as value of data_to_pass but in $_POST[‘user_id’] since user_id is input in my form no thing appear
Thank you so much ! I was all I need
Thank you – this was SUPER helpful and exactly what I needed.