Ruby on Rails with text_field_with_auto_complete

I spent some time trying to figure out how to get a little text field with auto complete in Rails. Now I wanted many fields to have the same suggestions in one form. So here are some code samples. For some information. I have a model that is called Locations, basically this is just a collection of names of cities a person should be able to travel to.
In my controller I need

# The first value is the model the second the name of the field

auto_complete_for :location, :name

# As of rails version > 2.0 forgery protection is activated by default. As the
# AJAX stuff won't work otherwise you have to disable it for one method

protect_from_forgery :except => [:auto_complete_for_location_name]

# This is the method called my the AJAX obj
def auto_complete_for_location_name
leg= params[:location].keys[0] # get index as its always only one at a time

auto_complete_responder_for_name params[:location][leg][:name]

# This does the real magic. It queries the database and then renders a
# partial 'names' with the list of values to display. With some sql knowledge

# you should be able to understand the query
def auto_complete_responder_for_name(value)
param= '%' + value.downcase + '%'
find_options= {
:conditions => [ 'LOWER(name) LIKE ?', param ],
:order => 'name ASC',
:limit => 10
@names = Location.find(:all, find_options)
render :partial => 'names'


So that is for the controller. Now we need to create the partial. You can call this what ever you want but for now I called it names. So you need a file named '_names'

<ul class="autocomplete_list">
<% for name in @names -%>
<li class="autocomplete_item"><%= %> </li>
<% end -%>

This is quite simple it get's the array @names we built in the controller and builds an unordered list out of the elements.

Next we have to add a little helper method to the app/helpers/application_helper.rb file. This is basically the wrapper for the 'real' auto_complete_field.

# Methods added to this helper will be available to all templates in the application.

module ApplicationHelper

def my_text_field_with_auto_complete(object, method, tag_options = {}, completion_options = {})
tag_name = "#{object}_#{tag_options[:index]}_#{method}"

tag_name = "#{object}_#{method}"

(completion_options[:skip_style] ? "" : auto_complete_stylesheet) +
text_field(object, method, tag_options) +
content_tag("div", "", :id => tag_name + "_auto_complete", :class => "auto_complete") +
auto_complete_field(tag_name, { :url => { :action => "auto_complete_for_#{object}_#{method}" } }.update(completion_options))


So now we should have everything that is needed to create our little textbox. Now in the view you just add
<%= my_text_field_with_auto_complete :location, :name, {:index => '1'} %>
And you increment the index value for every new field you add in that view.

Thank you to Wolfmans Howlings for posting all this.


elgocho said...

I'm trying to do the auto_complete example but I can't make it work, I have a question. I have to created a style sheet with any name? I put all the code together but it doesn't show anything, I'm working with (rails (2.1.1, 2.1.0)). If you can help please!!! sorry for my English!!

Ribalba said...

Hey I can't find your email. Just send me one, you can find it on