Monday, November 18, 2019

How to Create an AJAX-Powered Live Product Search Widget for WooCommerce

How to Create an AJAX-Powered Live Product Search Widget for WooCommerce

AJAX (Asynchronous Javascript and XML) is a way of getting a web page to communicate with a server, updating its content without reloading the page. In WooCommerce AJAX enables us to add products directly to the shopping cart, customize products on the fly, filter product lists, and much more.

In this tutorial we’re going to build a product “live search” plugin, with a product category filter and keyword input. All, of course, powered by AJAX.

Our plugin will give us a custom widget which can then be placed anywhere in the WooCommerce store. It will look like this (the aesthetics will change depending on the WordPress theme you’re using):

ajax product search

1. Create the Plugin Folder

Begin by creating a folder called “product-search” and the main php file within it “product-search.php”. Open the file and add the following header comment, changing the pertinent details to your own:

Here we describe what our plugin is and what it does. I won’t cover plugin development in details as that”s beyond the scope of this tutorial, but if you are new to plugin development, I highly recommend taking a look at this beginner’s course:

2. Plan Our Plugin Development

So here is our plan: we will have a search input with a select element to define the product category. All this will be packed inside a widget. Users will be able to search for a keyword within a specific product category.

Whenever the user enters a product keyword or product SKU we will make an AJAX request to query products that match the category (if defined), and contain the given keyword in the title, content, or match the given SKU. The user will be presented with a list of search results. 

Our next step is to enqueue the plugin style and script files.

3. Enqueue Plugin Files

Add the following code after the plugin intro:

Make sure you create corresponding folders for styles and scripts (css and js folders) and the corresponding files (style.css and main.js).

For the main.js file we will need to pass some parameters with the wp_localize_script function. These parameters give us the AJAX url and the “no results text” so we don’t have to hardcode them into our script.

4. Get Product Category Taxonomy with Hierarchy

Next we will need to collect and cache all the product categories with hierarchy. This will be used for the category select options.

This task has 4 steps:

  1. Get product category taxonomy with hierarchy
  2. List product category taxonomy with hierarchy as select options
  3. Cache the product category taxonomy results
  4. Delete product categories transient (cache) on term edit and post save

Get Taxonomy

Here I’ve created a recursive function that collects the given taxonomy terms with the parent child relationship:

List Product Categories as Select Options

Next we need to list the collected terms with another recursive function. It creates the option and optgroup based HTML structure:

Cache the Product Category Results

Queried results need to be cached so as not to slow down the filter render process. So here we need to create a transient for product categories. I won’t describe in detail the Transients API, but if you are new to the topic I highly recommend reading these amazing introduction tutorials:

For now, here is the product category transient:

Delete Product Categories Transient (Cache) on Term Edit and Post Save

Finally we need to delete the transient whenever a user updates or creates a product category, or updates/creates the product itself.

We will add actions for create_term, edit_term, delete_term and save_post

5. Create the Widget

Now it’s time to create the widget itself. I won’t describe in detail the widget creation process, but if you need to get up to speed I recommend this tutorial:

For now, add the following code to create the widget:

Our widget has no options, but does allow you to enter a title. It is a simple form with one search field and a category select. And for the category select we use the function we created earlier:

get_product_categories_hierarchy and list_taxonomy_hierarchy_no_instance. Also, we will need an SVG file to denote the loading when making the AJAX query.

For now, if you go to Appearance > Widgets you will see a new widget available, so you can add it to the widget area and see the following on the front end:

search widget

Looking awful! Let’s add some styles. 

6. Add Some Styles

Open the style.css file and add the following:

Now refresh the browser, (don’t forget about browser cache) and your widget should look much better:

product search

For now, it does nothing at all, so let’s apply some functions. 

7. Add Search Functions

Open the main.js file; here we’ll create our core search functionality. 

The idea is simple: we will add event listeners to search input keyup (typing) and select field change. Whenever any of these events fire we will make an AJAX request to send the keyword, query products based on the keyword, and output the given results. 

Add the following code to the main.js file:

Here we’ve defined some required variables and added event listeners to the select search. As you can see both events trigger the same function productSearch that has several parameters:

  • form
  • query
  • currentQuery
  • timeout;

productSearch Function

We don’t actually have that function yet, so the search won’t work for now, so let’s create that function. Add the following code right before the earlier one.

In this function we first make sure that our keyword has at least 3 characters in it and doesn’t have and spaces

Next, if our keyword length is more or less equal to 3 characters we add the loading class to the search field parent wrapper–this is required to run the CSS animation while we are making our AJAX request.

And here we will need to check the keyword entered doesn’t equal the current keyword, to avoid double AJAX requests on the same keyword. Next we set the Timeout for 500ms and make an AJAX request. With the request we pass the keyword, category and the AJAX request action search_product.

As we don’t have search_product action yet we will get an internal server error when making the AJAX. So let’s now create that action.

search_product Action

Open the main product-search.php file and at the very bottom add the following code:

For now, pay attention to the add_action part of the code. See the action names, with the prefixes wp_ajax_ and wp_ajax_nopriv_? We must use the same action names as we specified in the main.js file–search_product.

Now the Action Core

Here we are using the $wpdb query method to speed up the query process. I am no MySQL guru, so I guess the professionals can make it more optimized, but for our task it is good enough and working as expected. 

Here we first check if any category was specified, then query results under that specific category. If no category is specified we perform a regular product query that contains the keyword in the title, or the content, or matches the SKU. And if we have the results we create the output based on the queried results.

Now back to the main.js. If our AJAX request is successful we return the output data in the list and append to the search-results empty div. All that remains is to clear the timeout.

searching logo items

That’s it! An effective and powerful product AJAX search. Now if you go to the front-end, reload the page (don’t forget about the browser caching) you can search for products and see the widget in action.

Conclusion

You are free to use this plugin in your projects, both commercial and non-commercial. I hope you like and if you have any ideas you are free to write in comments section. You can download the plugin from GitHub. And here is the plugin demo. Thanks for reading!


No comments:

Post a Comment