Ruby on Rails
How to use text_field_with_auto_complete

Rails2.0: auto_complete is now a plugin (it’s not in the core anymore), you will install it before using it:

script/plugin install auto_complete

Working with this new addition is pretty easy, but there’s a few things that might be helpful to know if you want something non-default. Code snippets are from my stab at adding auto complete searching to Typo

Somewhere in your views you’ll want code somewhat like the following.

  1. Include the JavaScript necessary as per How to use the Ajax helpers.
  1. In your specific view include
<%= text_field_with_auto_complete :article, :contains, { :size => 15 }, :skip_style => true -%>

I specified a size for the text area with the :size => 15 values in the hash. I also included :skip_style => true which keeps the helper from automatically inlining CSS styles into the page.

You’ll then need to add a function to your controller, to actually do the search you’re wanting. Notice the name of the function starts with auto_complete_for and is followed by the two symbols you fed to the helper in your view.

def auto_complete_for_article_contains
  search = params[:article][:contains]
  @articles = Article.search(search) unless search.blank?
  render :partial => "live/search" 
end

I then added the partial that’s going to be rendered when the auto_complete function is called. Notice that the ul and li elements have class names, the prototype libs don’t seem to like elements if they don’t have an assigned class.

<ul class="autocomplete_list">
  <% for article in @articles.to_a -%>
    <li class="autocomplete_item"><%= article_link article.title, article %></li>
  <% end -%>
</ul>

There’s two links on scriptaculous that’re worth looking into, the Simpleajax/autocompleter and the Advancedajax/autocompleter_customized examples.

I still haven’t found solid answers to the following questions:

Answer: define a CSS class with the name of ‘selected’:


li.selected { background-color:#bbf; }

Would make a bluish highlighting color.

It is important to define a proper CSS stylesheet to see the effect. The class name for the drop-down list is “auto_complete”. Add the following definitions to your CSS file. The property “background-color: #bbf;” would make a bluish highlighting color.


.auto_complete {
      position:absolute;
      width:250px;
      background-color:white;
      border:1px solid #888;
      margin:0px;
      padding:0px;
}

.auto_complete ul {
      list-style-type: none;
      margin:0px;
      padding:0px;
}

.auto_complete ul li.selected 
{ 
        background-color: #bbf;

}

.auto_complete ul li {
      list-style-type: none;
      display:block;
      margin:0;
      padding:2px;
      height:16px;
}

JamesWu?

Also, Don’t Forget…
Remember to set :skip_style => true to override default auto_compete stying and pick up your custom settings.

The reason it’s not quite as simple as the demos is that autocompletion is not really intended for searching in this way. However, it can be used that way, and this is a good howto for doing that

MattMoriarity

Q: I don’t know if this is specified elsewhere, but you need to include several of the javascript libraries to make this work. I was only including protoype.js, which didn’t get everything going. Adding effects.js and controls.js made it work.

Answer:
Yes. You need prototype.js, controls.js, effects.js. Simply add the following line at the beginning of your rhtml file:


  <%= javascript_include_tag  :defaults %>

Make sure that you have prototype.js, controls.js, and effects.js, etc. in the javascripts directory of your web server.

If you want to be able to select multiple items in the one input box delimited by a certain token then simply add:

to the final argument hash in text_field_with_auto_complete which will make the first example look like:

<%= text_field_with_auto_complete :article, :contains, { :size => 15 }, {:skip_style => true, :tokens => ","}%>

—will c

Q. Has anyone had any difficulty using text_field_with_auto_complete with ModelSecurity? Once I enable Model Security, I get a “cannot convert Symbol to String” error on the first symbol.
A. Yup, unfortunately. I was able to get the generic autocompletion going by disabling the filters. Even that ‘solution’ hasn’t allowed me to use customized autocompletion though. :(
A. I’ve had problems with the cannot convert Symbol to String error in all my forms with ModelSecurity. The workaround is to use strings instead of symbols, for example :controller => 'post'. I really like ModelSecurity but issues like this are a constant headache. If there are enough people using it, we should consider taking over development since Bruce Perens is clearly too busy.

Note: This is the harder way of doing live search. You are better off using the observe_field directive. See the rails book or this link for a hint on how to do it.

Q. Does anyone know if you can use JavaScript effects with this tag? e.g. add a :loading => “new.Elem… to show a spinner while it’s loading?

Answer:


<%= text_field_with_auto_complete :article,
                                  :containes,{},
                                  :indicator => "activity_indicator"   %>

Q. Does anyone know how to get an ID back, in stead of a String?

Answer: A snippet from another page (http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter) regarding this. Translating their code to rails, it would be:

Another way to get aditional information, just send and ID in every list item, and redefine afterUpdateElement

<UL>
  <LI ID="1">Something</LI>
  <LI ID="2">Something else</LI>
</UL>

And:



<= text_field_with_auto_complete :model, :method, {}, :after_update_element => ‘getSelectionId’ >

In the head’s javascript:


function getSelectionId(text, li) { alert (li.id);
}

In addition there’s model_auto_completer, which extracts the ID and manages a hidden field for you.

Q I’m getting extra white spaces to the left of the selected item when I select one of the values from the ajax generated drop down? Is there a fix for this?

A in your partial file (_results.rhtml) have everything on one line with no spaces between the html elements.

Q How to set initial value of text_field_with_auto_complete

A


 <%= text_field_with_auto_complete :bond_rating,:rating,:value => @bondrating -%>

Q How to use :with parameter with text_field_auto_complete

A The only trick with :with is that you have to send in the text_fild parameter along with the additional data.


<%= text_field_with_auto_complete :article,
                                  :contains,
                                   {},
                                  :with => "'article[contains]='+encodeURIComponent(element.value)+'&search_field='+$('search_field').value",
                                  :skip_style => true    -%>

Turns out that text_field_with_auto_complete is invalid xhtml strict. If you try it it fails.
Disappointing for the anal retentive.

Q This (text_field_with_auto_complete) doesn’t seem to work with multiple forms on one page, is there a workaround? Or a safe way to avoid colliding symbol names?

A If you mean is there a way to have multiple text_field_with_auto_complete on the same form, then I have posted the recipe for doing that here http://blog.wolfman.com/articles/2006/10/17/having-multiple-text_field_with_auto_complete-in-the-same-view

Q How can I enter “foo” if there is “foobar” in the auto completion list?

A Press escape after typing “foo” and the list disappears.

Q How can I update another field with the response of the remote function call, used with :after_update_element (for instance, updating another div)? Or even, Say if disabled/hidden fieldset should be shown and then fields are filled with associated (by the id) Row data ?

Q hi it works fine until i let all values to show as one big drop ,but when i set the height and other css like overflow:auto,it is showing up as drop down where we can drag the side bar,it works fine on firefox but in IE,when i try to drag ,drop down is dissapearing,is there a way to fix this?thanks

Q how do you get around authenticity in Rails 2.0? When I add auto_complete_for as a plug-in I get the text field displayed as I should but get the following error in the log:

Processing BlogsController#auto_complete_for_section_name (for 127.0.0.1 at 2008-01-09 18:13:16) [POST]
  Session ID: d4f84ccec354491b3915f1f89bf6dd14
  Parameters: {"action"=>"auto_complete_for_section_name", "controller"=>"admin/blogs", "section"=>{"name"=>"hiki"}}

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
    /Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/request_forgery_protection.rb:79:in `verify_authenticity_token'

Thanks!

A
I use

skip_before_filter :verify_authenticity_token

in my controllers – sparingly as it will introduce insecurity into your app :(

cheers

A (pierre)
Don’t skip_before_filter !!

Apply this patch: http://dev.rubyonrails.org/ticket/10059

(if you don’t know how to apply a patch, just add these lines in
auto_complete/lib/auto_complete_macros_helper.rb:

if protect_against_forgery?
js_options[:parameters] = "'#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
end

just after the line:

js_options[:method] = ”’#{options[:method].to_s}’” if options[:method]