text_field_with_auto_complete

simple auto complete text field

on Mar 26 in blog posted , , , , by admin

I have been working on understanding the text_field_with_auto_complete functionality in Ruby on Rails for a project I am currently working on. There seems to be two written tutorials on the subject and they were a little confusing. Here is my attempt to be more specific.

Goal:

While editing an address record I want to show the user a short list of available suburbs that match what they have begun typing into he text box; and allow them to pick the one they want to use. When they save the record, I only want to store the ID of the suburb they typed in, not the actual text.

Solution:

Install the auto_complete gem:

ruby script/plugin install git://github.com/rails/auto_complete.git

This didn’t work on the windows system I was using, so I ended up having to grab the ZIP file and copy the contents to the ‘vendor/plugins/auto_complete’ folder the above command created.

First of all add to the site.rb model so we can refer to the suburb_name as if it was a field in the sites table:

def suburb_name
  suburb.name if suburb_id
end

def suburb_name=(value)
  self.suburb_id = Suburb.find_by_name(value.split(',')[0]).id unless value.blank?
end

Update the sites/edit.html.erb view to do the auto_complete markup:

<p>
  <%= f.label :suburb %><br />
  <%= text_field_with_auto_complete :site, :suburb_name, {}, :skip_style => false %>
</p>

Add an action to the sites_controller.rb so the auto_complete call(s) can get the short list:

def auto_complete_for_site_suburb_name()  
  @suburbs = Suburb.find(:all , :conditions=> "name like '%"+params[:site][:suburb_name].upcase+"%' and we_deliver_to=1")  
  render :partial => 'auto_complete_suburb_name'
end

Finally, create the _auto_complete_suburb_name.html.erb partial in the views/sites folder, the smallest form of which is like this

<ul><% for suburb in @suburbs do %><li><%=h suburb.name %>, <%=h suburb.postcode %></li><% end %></ul>

Important stuff you should know

  • I have added highlighting to illustrate the important connections between names as you move between view/model/controller. If you change one, you need to make the same change in every other occurence.
  • The suburbs table has no duplicates across the [name] field and no commas in any name value.
  • The COMMA in the partial is vitally important, I use it to tell the difference between the name value and the rest of the information that I don’t care about (the postcode). Use your own unique seperator if you have comma’s in your data.
  • No spaces in the _auto_complete_suburb_name partial, if you format it nicely your selected result will have lots of extra spaces (you’ll see what I mean)
  • There is no error checking in this. If the user types in a junk suburb the current code will not handle it gracefully.