AJAX Autocomplete with Catalyst

From Dev411: The Code Wiki

It is very easy to add AJAX autocomplete functionality to a Catalyst-based app using HTML::Prototype and the Catalyst prototype library and there is a good movie available on the Catalyst wiki movies page (http://dev.catalyst.perl.org/wiki/Movies). This page provides a some information on customizing the results which isn't discussed in the HTML::Prototype POD.

Table of contents

Getting Started

The first step is to ensure you are generating the autocomplete response yourself and not using HTML::Prototype's $prototype->auto_complete_result() method. The auto_complete_result method will automatically escape HTML which is needed in order to generate customized results.

Bold the User's Text

A common way to customize the result is to bold the text the user has entered so the user can quickly see why the resulting entries matched what was typed. This can be done with a simple Perl substitution regexp. The below only covers generating a bolded response.

my $text = $c->req->param('autocomplete_field');
my @items = qw/foo bar baz/;
my @matches = grep /$text/, @items;

# Bold the user's text
@matches = map { s/($text)/<strong>$1<\/strong>/g; $_ } @matches;

if (@matches) {
    # Make each item an HTML line item
    @matches = map { "<li>$_</li>" } @matches;

    # Set the output using an unordered list.
    $c->res->body( '<ul>'.join('',@matches).'</ul>' );
}

Display-only Text

Sometimes it's nice to provide some additional, descriptive information to the user that should not populate the text element. To supply text for display purposes only use a span with the class set to "informal" around the display-only text:

<ul>
    <li>Perl<span class="informal">(50,000 results)</span></li>
</ul>

CSS Formatting

The Script.aculo.us Wiki has a nice demo (http://demo.script.aculo.us/ajax/autocompleter_customized) using CSS formatting to get a description text under the main text using a different font. You'll have to use the browser's View Source option to get the CSS since they don't provide it on the page.