ExpressionEngine autocomplete search / jump menu with jQuery

This tutorial will show you how to build an text input that will give autocomplete / auto suggestions via AJAX straight from an ExpressionEngine template then redirect straight to the entry. It could be used for searching, or shortcuts to particular entries, I have it working for the latter on a recent project. It will allow you to …

  1. Start typing parts of an entry
  2. Scroll through the autocompleted suggestions that pop up
  3. Click one (or use the keyboard shortcuts)
  4. Get redirected to the relevant entry on the relevant page

1) Get all the bits you need!

This functionality depends on the following bits, so go get them downloaded and included in your site:

2) The templates

  • The index page is where we’ll house the autocomplete
  • The 2 javascript files will do the work for us
  • The single_entry template is where we’ll redirect to show the full entry
  • The _autocompleter is the template that will dynamically look up the entries as we type them

If you so wish you can download all the templates instead of reading through all the code here.

The index template

Include the Javascript and add a little CSS for the markup, there is some default css included with the autocompleter plugin. Then we’ll need to make the form and that all important input text box:

<h2>Autocomplete</h2> 
<!-- Form action can be anything - make sure it degrades nicely --> 
<form id="quickjump" action="/index.php/autcomplete/results/" method="post"> 
  <fieldset> 
    <p><label for="quickjump_title"></label><br /> 
    <!-- We'll scan this text field for matching entries --> 
    <input type="text" size="20" id="quickjump_title" name="quickjump_title" /></p> 
    <!-- Again the search button is just so it degrades --> 
    <button type="submit">Go</button></p> 
  </fieldset> 
</form>

We’ll then write the JavaScript to call the autocomplete plugin and handle the results

<script type="text/javascript"> 
$(document).ready(function(){ 
  // Autocomplete 
  $("input#quickjump_title").autocomplete("/index.php/autocomplete/_autocompleter/",{ 
    cacheLength: 0, 
    minChars: 3, 
    formatItem: function (row) { return row[0] }, 
    formatResult: function (row){ return row[1] } 
  }).result(function(event, item) { 
    //redirect to the URL in the string 
    window.location.href = "{path="autocomplete/single_entry"}"+item[1]; 
  }); 
}); 
</script>

You’ll notice the autocomplete url we’re calling is one of the templates, it must be referenced with /index.php/template_group/template/ with all slashes intact as well as index.php. The second part of that function will redirect the user to the single entry page with the correct url.

JAVASCRIPT ALTERATIONS

I mentioned I’d altered the script to use $_POST ajax calls rather than sending them in the url with $_GET. This means you can be a bit cleaner with the url you pass as well as enjoying a bit more security (if you enjoy that sort of thing;)

Firstly you’ll need to alter the jquery autocomplete source, lucky for us jQuery have made it really simple – we’ll use the $.ajaxSetup function to ensure we’re posting not getting the results. Download the complete pack and open the uncompressed file, then inside the request function we’re going to set the params for ajax calls just before the $.ajax({ call. At the time of writing that’s at about line 361. Just add the following:

$.ajaxSetup({ type: "POST" });

Make sure it’s before that $.ajax({ call.

You can now remove the /index.php/ part of the request url so it will look like

$("input#quickjump_title").autocomplete("/index.php/autocomplete/_autocompleter/",{ 
...

The _autocompleter template

This template needs to have PHP switched on at the input stage (see the template options)

Pretty simple once we’re in though:

{exp:weblog:entries weblog="thoughts" search:thought_body="<?php echo $_GET['q'] ?>"}
{exp:char_limit total="20"}{exp:html_strip}{thought_body}{/exp:html_strip}{/exp:char_limit}|{url_title}
{/exp:weblog:entries}

I’m using it to access my thoughts weblog, your settings will probably be different, you can adjust as you need. What we’re returning though are pipe separated rows “excerpt|url_title” the autocompleter plugin will do the rest. The PHP is just picking the variable from the url (passed by AJAX) and using the search parameter in the entries tag.

Single entry template

You probably don’t need me to help you here, it’s just a template to pick out the single entry based on the url:

{exp:weblog:entries weblog="thoughts" limit="1"}
<h2>{title}</h2>
{thought_body}
{/exp:weblog:entries}

Simples.

As usual, any questions post them up – I mean to revise and improve this post over time and I’d appreciate your feedback.