The WordPress search form doesn't offer any bells and whistles by default. If it's already included in your theme, or you've added the search widget to one of your sidebars, you can attest to that. One way to greatly improve its functionality is to include an autocomplete script to help enhance the efficiency of how relevant search queries are relayed.
Twitter typeahead.js
There are quite a few autocomplete scripts available and recently Jake Harding from Twitter released typeahead.js, a completely independent version of a similarly named script that comes packaged with Bootstrap. I thought it would be interesting to figure out how to use this lightweight script with WordPress, and after a bit of fumbling around, I managed to put together a little plugin with the help of Michal Bluma.
WP Typeahead Plugin
The plugin is pretty straightforward since there's only a little bit of customization that is needed to get things working properly. I'll break down each section of the plugin code for you to explain what's going on.
Basic Plugin Setup
<?php /* Plugin Name: WP Typeahead Description: Add autocomplete search functionality to default WordPress search form Author: c.bavota, Michal Bluma Version: 1.0.0 Author URI: http://www.bavotasan.com/ */ class Bavotasan_WP_Typeahead { public $plugin_url; public function __construct() { $this->plugin_url = plugin_dir_url( __FILE__ ); add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) ); add_action( 'wp_ajax_nopriv_ajax_search', array( $this, 'ajax_search' ) ); add_action( 'wp_ajax_ajax_search', array( $this, 'ajax_search' ) ); } } $bavotasan_wp_typeahead = new Bavotasan_WP_Typeahead;
On its own, the above code will only spit out some errors but this is the start of everything that you need to use typeahead.js with the WordPress search form. The first action is there to enqueue the JavaScript / CSS files you need and place the required JS in the footer. Next come the Ajax calls to help out with the search results. Let's take a look at each function.
Enqueueing
/** * Enqueue Typeahead.js and the stylesheet * * @since 1.0.0 */ public function wp_enqueue_scripts() { wp_enqueue_script( 'wp_typeahead_js', $this->plugin_url . 'js/typeahead.min.js', array( 'jquery' ), '', true ); wp_enqueue_script( 'wp_hogan_js' , $this->plugin_url . 'js/hogan.min.js', array( 'wp_typeahead_js' ), '', true ); wp_enqueue_script( 'typeahead_wp_plugin' , $this->plugin_url . 'js/wp-typeahead.js', array( 'wp_typeahead_js', 'wp_hogan_js' ), '', true ); $wp_typeahead_vars = array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ); wp_localize_script( 'typeahead_wp_plugin', 'wp_typeahead', $wp_typeahead_vars ); wp_enqueue_style( 'wp_typeahead_css', $this->plugin_url . 'css/typeahead.css' ); }
There are four files that need to be enqueued. First is the actual typeahead.js file, then the templating engine called hogan.js, followed by a new JavaScript file we'll create to put everything in motion, and finally the stylesheet that makes it all look good.
You'll notice in the middle there we also use wp_localize_script
to make the Ajax URL available for our JavaScript.
The Footer Script
( function($) { $( 'input[name="s"]' ) .typeahead( { name: 'search', remote: wp_typeahead.ajaxurl + '?action=ajax_search&fn=get_ajax_search&terms=%QUERY', template: [ '<p><a href="{{url}}">{{value}}</a></p>', ].join(''), engine: Hogan } ) .keypress( function(e) { if ( 13 == e.which ) { $(this).parents( 'form' ).submit(); return false; } } ); } )(jQuery);
Put this into the new /js/wp-typeahead.js file. The jQuery selector above will attach the typeahead function to any of the default WordPress search forms and use the Hogan templating engine to format the returned Ajax data. Sometimes, the search form can be modified by your theme and the submit button will be removed so I've added in a little script to make sure that when you hit the enter button, the search form is actually submitted.
The Ajax Query
/** * Ajax query for the search * * @since 1.0.0 */ public function ajax_search() { if ( isset( $_REQUEST['fn'] ) && 'get_ajax_search' == $_REQUEST['fn'] ) { $search_query = new WP_Query( array( 's' => $_REQUEST['terms'], 'posts_per_page' => 10, 'no_found_rows' => true, ) ); $results = array( ); if ( $search_query->get_posts() ) { foreach ( $search_query->get_posts() as $the_post ) { $title = get_the_title( $the_post->ID ); $results[] = array( 'value' => $title, 'url' => get_permalink( $the_post->ID ), 'tokens' => explode( ' ', $title ), ); } } else { $results[] = __( 'Sorry. No results match your search.', 'wp-typeahead' ); } wp_reset_postdata(); echo json_encode( $results ); } die(); }
When something is typed into the search form, typeahead.js will take it and submit it through Ajax using the remote parameter from the code in the last step. That text has to pass through a function in order for it to be useful and that's why you need the little snippet above.
It takes the search text, runs it through a WordPress query to return any relavent results if they exist. Those results are sent back after being encoded using JSON so that the script can read the data properly.
The Completed Code
With everything in place, the main plugin file should look like this...
<?php /* Plugin Name: WP Typeahead Description: Add autocomplete search functionality to default WordPress search form Author: c.bavota, Michal Bluma Version: 1.0.0 Author URI: http://www.bavotasan.com/ */ class Bavotasan_WP_Typeahead { public $plugin_url; public function __construct() { $this->plugin_url = plugin_dir_url( __FILE__ ); add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts' ) ); add_action( 'wp_ajax_nopriv_ajax_search', array( $this, 'ajax_search' ) ); add_action( 'wp_ajax_ajax_search', array( $this, 'ajax_search' ) ); } /** * Enqueue Typeahead.js and the stylesheet * * @since 1.0.0 */ public function wp_enqueue_scripts() { wp_enqueue_script( 'wp_typeahead_js', $this->plugin_url . 'js/typeahead.min.js', array( 'jquery' ), '', true ); wp_enqueue_script( 'wp_hogan_js' , $this->plugin_url . 'js/hogan.min.js', array( 'wp_typeahead_js' ), '', true ); wp_enqueue_script( 'typeahead_wp_plugin' , $this->plugin_url . 'js/wp-typeahead.js', array( 'wp_typeahead_js', 'wp_hogan_js' ), '', true ); $wp_typeahead_vars = array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ); wp_localize_script( 'typeahead_wp_plugin', 'wp_typeahead', $wp_typeahead_vars ); wp_enqueue_style( 'wp_typeahead_css', $this->plugin_url . 'css/typeahead.css' ); } /** * Ajax query for the search * * @since 1.0.0 */ public function ajax_search() { if ( isset( $_REQUEST['fn'] ) && 'get_ajax_search' == $_REQUEST['fn'] ) { $search_query = new WP_Query( array( 's' => $_REQUEST['terms'], 'posts_per_page' => 10, 'no_found_rows' => true, ) ); $results = array( ); if ( $search_query->get_posts() ) { foreach ( $search_query->get_posts() as $the_post ) { $title = get_the_title( $the_post->ID ); $results[] = array( 'value' => $title, 'url' => get_permalink( $the_post->ID ), 'tokens' => explode( ' ', $title ), ); } } else { $results[] = __( 'Sorry. No results match your search.', 'wp-typeahead' ); } wp_reset_postdata(); echo json_encode( $results ); } die(); } } $bavotasan_wp_typeahead = new Bavotasan_WP_Typeahead;
When you download the plugin, you'll have the stylesheet and required JS files included within the ZIP file.
Conclusion
Adding an autocomplete script to your search form can help your users navigate through your site more easily. That means a better overall experience which will hopefully lead to more repeat visits and higher traffic. This plugin just needs to be activated in order for it to work with your search forms.
If you have any comments or feedback on anything you read above, please feel free to discuss it below.
Comments