Autocompleting a Text Field

Problem

You want to create a text field that automatically completes the rest of a word fragment or partial phrase as the user enters it.

Solution

Use the autocompletion feature of the script.aculo.us JavaScript library.

You need to define a list of possible matches for autocompletion to search. This solution draws from a list of musicians in a database. Define a musicians table, and populate it with a migration:

db/migrate/001_create_musicians.rb:

class CreateMusicians < ActiveRecord::Migration
 def self.up
 create_table :musicians do |t|
 t.column :name, :string
 end
 Musician.create :name => 'Paul Motion'
 Musician.create :name => 'Ed Blackwell'
 Musician.create :name => 'Brian Blade'
 Musician.create :name => 'Big Sid Catlett'
 Musician.create :name => 'Kenny Clarke'
 Musician.create :name => 'Jack DeJohnette'
 Musician.create :name => 'Baby Dodds'
 Musician.create :name => 'Billy Higgins'
 Musician.create :name => 'Elvin Jones'
 Musician.create :name => 'George Marsh'
 Musician.create :name => 'Tony Williams'
 end
 def self.down
 drop_table :musicians
 end end

Then associate the table with an Active Record model:

app/models/musician.rb:

class Musician < ActiveRecord::Base end

Next, use the javascript_include_tag in your layout to include the script.aculo.us and Prototype JavaScript libraries.

app/views/layouts/musicians.rhtml:

<html>
<head>
 <title>Musicians: <%= controller.action_name %></title>
 <%= javascript_include_tag :defaults %>
</head>
<body>
<%= yield %>
</body>
</html>

The controller contains a call to auto_complete_for; the arguments to this method are the model object and the field of that object to be used for completion possibilities:

app/controllers/musicians_controller.rb:

class MusiciansController < ApplicationController
 auto_complete_for :musician, :name
 def index
 end
 def add
 # assemble a band...
 end end

The field being completed will typically be used as part of a form. Here we create a simple form for entering musicians:

app/views/musicians/index.rhtml:

<h1>Musician Selection</h1>
<% form_tag :action => :add do %> 
 <%= text_field_with_auto_complete :musician, :name %>
 <%= submit_tag 'Add' %>
<% end %>

Discussion

The script.aculo.us JavaScript library provides support for autocompletion of text fields by displaying a list of possible completions as text is being entered. Users can enter a portion of the text and select the complete word or phrase from a drop-down list. As more text is entered, the list of suggested completions is continually updated to include only possibilities that contain that text. The matching is case insensitive, and a completion is selected with the Tab or Enter keys. By default, 10 possibilities are displayed in ascending alphabetical order.

The call to auto_complete_for in the controller takes the model, and the field to search in that model, as arguments. An optional third argument is a hash that lets you override the defaults for what possibilities are selected and how they're returned. This hash can contains any option accepted by the find method.

demonstrates how a list of possible completions are displayed as text is entered.

Figure 8-8. A text input field with an autocomplete drop-down menu

See Also