Advertisement
Plugins

Enhancing the Search Form With typeahead.js

by

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.

Related Posts
  • Code
    Theme Development
    How to Pass PHP Data and Strings to JavaScript in WordPressPhp js 400
    It's good practice to put all your data in static strings in your PHP files. If you need to use some data in JavaScript later on, it's also good practice to put your data as data-* attributes in your HTML. But in some certain scenarios, you have no choice but to pass strings directly to your JavaScript code. If you are including a JavaScript library, and you've found yourself initializing a JavaScript object inside your header.php then assigning data to its properties, then this article is for you. This article will teach you on how to properly pass PHP data and static strings to your JavaScript library.Read More…
  • Code
    Creative Coding
    Using the Included Password Strength Meter Script in WordPressPassword meter 400
    WordPress uses a pretty nifty password strength script that is used to display whether the passwords you entered in the WordPress admin are: not the same, very weak, weak, medium or strong. Currently this script is only used when creating creating new users and when changing your password in your admin. In this article, I will be teaching you on how to use the WordPress' password strength meter in your own forms.Read More…
  • Code
    Plugins
    Using HighCharts in WP-AdminHighcharts 400
    Charts are a great way to present data. They make data more digestible by making it visually appealing. In WordPress, there is no built-in method for getting posts and pages data in a graphical form. Although, there are certain plugins available which integrate Google Analytics with WordPress, but they are overkill if you want to get only a portion of that data. Also, nothing should keep you from learning new techniques and to dive straight into the subject is the best way to learn.Read More…
  • Code
    Theme Development
    Ensuring Your Theme Has Retina SupportRetina 400
    With all of the high resolution screens available today, it only makes sense that your WordPress theme includes support for displaying higher quality images. That means adding functionality to create these images on top of a way to load the right one depending on the screen resolution of the end user.Read More…
  • Code
    Cheat Sheets
    The Complete Guide to Proper JavaScript Usage With WordPressJavascript 400
    I remember thinking "What the heck do we need JavaScript for, when we have Flash?" when I was fourteen. Although I still remember how I enjoyed coding stuff with ActionScript 2.0 back then, I saw how much one can achieve with JavaScript and fell in love with it. I'm not an expert on JavaScript (yet) but I can say I'm over and done with Flash for a long time. When it comes to WordPress, the biggest blogging platform and content management system worldwide, JavaScript is - of course - very useful for many things: content sliders, lightbox galleries, slick shopping carts, UI elements like tabs or accordions... you name it. But how exactly should we use JavaScript with WordPress? Returning or echoing a bunch of HTML script elements is one way to do it - and it's wrong. In this tutorial, we're going to see how to enqueue JavaScript files inside our pages and how to pass translatable data to the JavaScript code.Read More…
  • Code
    Plugins
    A Better Forum List Widget for bbPressBbpress
    When bbPress was still a standalone installation, I had tried it out and wasn't really impressed. Things were clunky and it didn't always work the way it was supposed to. After languishing for a few years, Automattic decided to take bbpress and turn it into a plugin, improving the functionality leaps and bounds and making it a strong contender amongst other forum option for WordPress.Read More…