AJAX autocomplete based on a static table in the database

I have a field where a user enters his city. I want to add autocompletion to this field based on a table with a predefined set of cities not based on previous entries of other users. How can I do this?

I know about the method described in rails recipes which allows to cache a predefined set of values for autocompletion (Autocomplete.Local). This is not what I'm looking for though because my list of cities is very long and I don't want to cache it.

Thanks, Aeneas

You can write your own "auto_complete_for_#{object}_#{method}" method pretty easily, rather than calling auto_complete_for to generate it for you. The source code of auto_complete_for is a good starting point.

-- James

Thanks James. I solved the problem now. It's really easy. In your controller you just replace

auto_complete_for :ad, :city

with

  def auto_complete_for_ad_city     @cities = City.find(:all)     render :inline => "<%= auto_complete_result(@cities, 'name') %>"   end

For this to work you will need a table called cities and a city model.

Aeneas

I still have one probelm though. The soruce for auto_complete_for is as follows:

37: def auto_complete_for(object, method, options = {}) 38: define_method("auto_complete_for_#{object}_#{method}") do 39: find_options = { 40: :conditions => [ "LOWER(#{method}) LIKE ?", '%' + params[object][method].downcase + '%' ], 41: :order => "#{method} ASC", 42: :limit => 10 }.merge!(options) 43: 44: @items = object.to_s.camelize.constantize.find(:all, find_options) 45: 46: render :inline => "<%= auto_complete_result @items, '#{method}' %>" 47: end 48: end

However, the following adaption dowsn't work (in the controller):

  def auto_complete_for_ad_city     @items = City.to_s.camelize.constantize.find( :all,             :conditions => [ "LOWER(name) LIKE ?", '%' + params[ad][city].downcase + '%' ],             :order => "name ASC",             :limit => 10           )           render :inline => "<%= auto_complete_result(@items, 'name') %>"   end

the part causing problems is params[city][name]. Is this really the variable which stores the letters typed into the field ad[city]? The error message is: undefined local variable or method `ad' for #<AdsController:0xb79908c0>

Any ideas?

Aeneas

I still have one probelm though. The soruce for auto_complete_for is as follows:

37: def auto_complete_for(object, method, options = {}) 38: define_method("auto_complete_for_#{object}_#{method}") do 39: find_options = { 40: :conditions => [ "LOWER(#{method}) LIKE ?", '%' + params[object][method].downcase + '%' ], 41: :order => "#{method} ASC", 42: :limit => 10 }.merge!(options) 43: 44: @items = object.to_s.camelize.constantize.find(:all, find_options) 45: 46: render :inline => "<%= auto_complete_result @items, '#{method}' %>" 47: end 48: end

However, the following adaption dowsn't work (in the controller):

  def auto_complete_for_ad_city     @items = City.to_s.camelize.constantize.find( :all,             :conditions => [ "LOWER(name) LIKE ?", '%' + params[ad][city].downcase + '%' ],             :order => "name ASC",             :limit => 10           )           render :inline => "<%= auto_complete_result(@items, 'name') %>"   end

the part causing problems is params[city][name]. Is this really the variable which stores the letters typed into the field ad[city]? The error message is: undefined local variable or method `ad' for #<AdsController:0xb79908c0>

Any ideas?

Aeneas

Did you really mean this instead?

params[:ad][:city]

If that's not where your trouble lies, look at your development log file. Every param is logged there, so you should be able to see the names being used.

-- James

JDL wrote:

> > I still have one probelm though. The soruce for auto_complete_for is as > follows: > > 37: def auto_complete_for(object, method, options = {}) > 38: define_method("auto_complete_for_#{object}_#{method}") do > 39: find_options = { > 40: :conditions => [ "LOWER(#{method}) LIKE ?", '%' + > params[object][method].downcase + '%' ], > 41: :order => "#{method} ASC", > 42: :limit => 10 }.merge!(options) > 43: > 44: @items = object.to_s.camelize.constantize.find(:all, > find_options) > 45: > 46: render :inline => "<%= auto_complete_result @items, > '#{method}' %>" > 47: end > 48: end > > However, the following adaption dowsn't work (in the controller): > > def auto_complete_for_ad_city > @items = City.to_s.camelize.constantize.find( :all, > :conditions => [ "LOWER(name) LIKE ?", '%' + > params[ad][city].downcase + '%' ], > :order => "name ASC", > :limit => 10 > ) > render :inline => "<%= auto_complete_result(@items, 'name') > %>" > end > > the part causing problems is params[city][name]. Is this really the > variable which stores the letters typed into the field ad[city]? The > error message is: undefined local variable or method `ad' for > #<AdsController:0xb79908c0> > > Any ideas?

Did you really mean this instead?

params[:ad][:city]

If that's not where your trouble lies, look at your development log file. Every param is logged there, so you should be able to see the names being used.

-- James

Thanks, that was it!

So for the archive here the working version:

  def auto_complete_for_ad_city     @items = City.to_s.camelize.constantize.find( :all,             :conditions => [ "LOWER(name) LIKE ?", '%' + params[:ad][:city].downcase + '%' ],             :order => "name ASC",             :limit => 10           )      render :inline => "<%= auto_complete_result(@items, 'name') %>"   end