Page tree
Skip to end of metadata
Go to start of metadata

Your Rating: Results: 1 Star2 Star3 Star4 Star5 Star 100 rates

To enhance the search across Magnolia CMS content you can autocomplete the search terms entered by the user. Autocomplete, or word completion, is a feature that predicts the word or phrase the user wants to type in without the user actually typing it in completely. It displays a list of potential search terms dynamically. This is done by extracting the search terms from the underlying content index and completing them with a client-side JavaScript. You can see an example on The keywords are stored in a JavaScript file. Some more JavaScript is added to the page to provide this functionality. The keywords in the .js file must be updated periodically.

An alternative AJAX-based autocomplete approach is described in Rendering paragraphs with AJAX. Here are the pros and cons of each approach.

JavaScript approach (on this page):

  • Faster than AJAX because the JavaScript file that holds the search keywords can be cached together with the page. You don't have to connect to the server to get the new terms.
  • The keyword file must be regenerated manually when a new term is added to the index. This means that the autocompleted terms are not always in sync with the index.
  • Works well if the site content does not change often or it changes only at known times and you generate a new JavaScript file after each content update.

AJAX approach:

  • Slower. Queries the server every time the user requests new autocompletion. The result set can be very large and take a lot of memory.
  • You can speed up the search for example by executing the query only after the user has typed the first three letters. Smaller result set.
  • Works well when content changes often. The completed keywords are always in sync with the content index.
  • Works well when you limit the search to a subset of content. For example, search only contacts or only FAQ pages. Smaller result set is faster to work with.
  • You need to write a new class for each new subset of content.

Add name and id attributes in the input field

Add name and id attributes in the input field. Set their value to query. Add a div element with id autosuggest somewhere on the page. This div will be dynamically attached to your search field.

Here is an code snippet from my homepage:

Input field and div element
<input type="text" size="8" name="query" id="query" value="" />
<div id="autosuggest"><ul></ul></div>

Add a tag

You need a tag that is called in one of your templates that actually reads the search terms from the index and writes them to the .js file. Since the JCP can be run with different implementations, the tag uses internally an specific implementation for your corresponding index. In my case it is the Jackrabbit implementation (this is the one that comes with Magnolia samples). Therefore you need to add three files to your classpath.

The tag returns the path to the written .js file. For example

<script src="/<your path>/js/index_terms1143670016645.js" type="text/javascript"></script>.

The file that is generated by the tag is index_terms1143670016645.js. Note that the filename contains a timestamp. The javascript file with the search terms can become quite large. I want the client browser to cache it until I generate it the next time. Therefore it has the timestamp in the filename.

Import autosuggest JavaScript

Import the autosuggest.js file in your search page to attach the autosuggestion functionality. The JavaScript that does all the autosuggestion. The original script was written by Joe Kepley but his site is no longer available.

You would use something like this.

<script src="/<your path>/js/autosuggest.js" type="text/javascript"></script>

Import CSS styles

Import some styles to make everything look like a drop-down menu. This is a snipped of the CSS used for my autosuggest.

background: white;
border: 1px solid black;
padding: 4px;

.suggestion_list ul
padding: 0;
margin: 0;
list-style-type: none;

.suggestion_list a
text-decoration: none;
color: black;

.suggestion_list .selected
color: #B84800;

.suggestion_list .selected a
color: #B84800;

display: none;