If you’ve ever implemented type-ahead functionality and wondered how to get it to work when users are entering multiple items, like a list of comma delimited tags, here it is.
You can, of course, roll your own Javascript and Ajax calls but why bother when Rails gives us a nice Javascript helper to handle this. The helper is text_field_with_auto_complete but this defaults to the current controller. For my purposes tags can be entered on different areas of the site for different models so I used text_field_with_auto_complete with one modification:
def text_field_with_auto_complete_with_custom_url(object, method, url_options = {}, tag_options = {}, completion_options = {}) (completion_options[:skip_style] ? "" : auto_complete_stylesheet) + text_field(object, method, tag_options) + content_tag("div", "", :id => "#{object}_#{method}_auto_complete", :class => "auto_complete") + auto_complete_field("#{object}_#{method}", { :url => { :action => "auto_complete_for_#{object}_#{method}" }.update(url_options) }.update(completion_options)) end
Note: text_field_with_auto_complete is deprecated and will be moved to a plugin in Rails 2.0.
The third parameter is now a hash of optional url arguments (action, controller, etc). You can also monkey patch the original method or better use some alias/alias_method_chain trickery in your own app. In your view call the newly created helper with your arguments.
"tagging_demo"}, {}, { :tokens => ','} %>
Include the necessary javascript libraries (prototype and scriptaculous):
You can set the controller and action to whatever you like but it defaults to a method in the form of auto_complete_for_object_method. Going with that your action could look something like this:
def auto_complete_for_tag_names @tags = Tag.find(:all, :conditions => ["name like ?", "%#{params[:tag][:names]}%"], :order => 'name DESC', :limit => 20) render :layout => false end
And your view (auto_complete_for_tag_names.html.erb):
That’s all there is to it. The magic comes from providing a token to Ajax.Autocompleter which we provided in the argument hash to text_field_with_auto_complete_with_custom_url ( { :tokens => ‘,’} ). You can use any delimiter you like. You can also customize the UI in your view and CSS.