AJAX stands for “Asynchronous JavaScript and XML” and is a set of website development techniques that can be used to send and receive data from a server asynchronously.
AJAX can send and receive data in many different formats, including JSON, XML, HTML and plain text. The most appealing characteristic of AJAX is it decouples the data interchange layer from the presentation layer allowing web pages and web applications to communicate with the server and update a web page without having to refresh/reload the page.
WordPress uses AJAX by default in the admin dashboard. For example, when you are assigning a featured image to a post or page, WordPress utilizes AJAX to load the media library and, when an image is selected, AJAX is used to assign the image.
Similarly, WordPress also uses AJAX to save a draft of a post or page while you are still making changes. We can use the functions provided by WordPress to use AJAX and update content on the front-end of the site.
Let’s say we have a custom post type called “Products” and there are custom taxonomies for Products such as “Color” and “Size”.
On the front-end of the site, on the products archive page, drop-downs for Color and Size can be displayed above all the products to filter the products based on the selections made. The traditional way of filtering the products was to redirect the user to a taxonomy archive page based on the selection made or to reload the page with the filtered products when the filters were submitted by the user.
With AJAX, when the user chooses the options from the drop-downs and submits the request, the page can be updated without having to reload the page or redirect the user to a different page.
On the Products archive page, we could have a form above all the products to filter the products.
<form method="POST" action="" class="products-filter">
<select name="color" id="color" aria-label="Color">
<option value selected>Color</option>
<option value="red">Red</option>
<option value="white">White</option>
<option value="blue">Blue</option>
</select>
<select name="size" id="size" aria-label="Size">
<option value selected>Size</option>
<option value="small">Small</option>
<option value="medium">Medium</option>
<option value="large">Large</option>
</select>
<input type="submit" value="Filter Products" />
</form>
<div class="products">
// Display all products here
</div>
In the above form, the name
attribute for each select
corresponds to the taxonomy slug and the value
attribute for each option
corresponds to the slug for the taxonomy term.
Below the filter options, all products are displayed on the page using WP_Query inside the div
with class="products"
.
When the user makes the selection from the drop-downs and hits the “Filter Products” button, we want to take the user’s selections, make an AJAX call and filter the products based on it.
Below is the JavaScript code that is needed for this.
$('.products-filter').submit(function(e) {
e.preventDefault(); // Prevent the default action for the form
$.ajax({
type: 'POST',
url: '/wp-admin/admin-ajax.php',
dataType: 'json',
data: {
action: 'filter_products',
taxonomies: $(this).serializeArray(),,
},
success: function(res) {
$('.products').html(res);
},
error: function(err) {
console.error(err);
}
})
});
In the above JavaScript, we are preventing the default form submit behavior, and making an AJAX call utilizing the admin-ajax.php in the wp-admin folder. We will be posting our data to a custom function called “filter_products” and passing the slug for each selected taxonomy to our data ‘taxonomies’.
In the functions.php file in your theme, we need to write the “filter_products” function that is being called by the AJAX call.
function filter_products() {
$taxonomies = $_POST['taxonomies']; // Associative array of taxonomy=>taxonomy term slugs passed from the Ajax call
$tax_query = array(); // Initialize an empty array to store taxonomy query
$tax_count = 0; // To count the number of taxonomies passed as a relation parameter needs to be passed if there are more than 1
// Default arguments array
$args = array(
'post_type' => 'products',
'posts_per_page' => -1
);
// Loop through the posted taxonomies
foreach ($taxonomies as $taxonomy) { // Iterate through the taxonomies
if ($taxonomy["value"] != "") { // Only if value is present for taxonomy
array_push($tax_query, array('taxonomy' => $taxonomy['name'], 'field' => 'slug', 'terms' => $taxonomy['value'])); // Push the taxonomy query to the array
if ($tax_count > 0) $tax_query['relation'] = 'AND'; // Add 'relation' parameter if more than one
$tax_count++; // Increment counter
}
}
// Add taxonomy query if array is not empty
if (!empty($tax_query) {
$args['tax_query'] = $tax_query;
}
$ajaxposts = new WP_Query($args);
$response = ""; // Initialize empty response string
if ($ajaxposts->have_posts()) {
ob_start(); // Start the buffer
while (ajaxposts->have_posts()) {
ajaxposts->the_post();
// Either call a template part or include html to display products
}
$response = ob_get_content(); // Add the buffer contents to $response
ob_end_clean(); // Clear the buffer
} else {
$response = "No products found."
}
echo json_encode($response); // Echo the response
wp_reset_postdata();
exit; // this is required to terminate immediately and return a proper response
}
add_action('wp_ajax_filter_products', 'filter_products');
add_action('wp_ajax_nopriv_filter_products', 'filter_products');
In the above code, we are looping through the user selected taxonomies and creating a tax_query
array. Then we are adding the array to our $args
array and creating a new WP_Query class to loop through and display the products that have been assigned to the selected taxonomy/taxonomies.
The wp_ajax_filter_products
and the wp_ajax_nopriv_filter_products
are action hooks to fire authenticated AJAX actions for logged-in and not logged-in users respectively.
When the user makes the selection from the dropdown options and hits the “Filter Products” button, the HTML inside the div
with class="products"
will be updated with the new content.
Because of its asynchronous nature, AJAX is gaining popularity.
Not only does it reduce server traffic, but from a user’s point of view, it allows the user to browse through the webpage while data is being fetched in the background.
While I would not suggest developing an entire website in WordPress using AJAX as it does have certain drawbacks, in certain cases like the one discussed above, using AJAX would be an ideal solution.
If you need any help implementing AJAX on your website, reach out to us.