Advanced Auto Complete Feature (auto_complete ROR Plugin)

Vamsi Krishna

3 min read

Autocomplete is very common feature that we see in many web2.0 applications (as in google,youtube and so on), this feature is easily implemented in Rails using auto_complete plugin But, what I wanted to do one more ajax call upon selecting the item from auto complete list, Lets take a scenario I have a form where my I take user Information and his working company lets just say that company has few more details like address, state and country. If I type a character in my company name textbox I should be able to see all the companies If I select any one company name from the list based on that company it should fill it address,state and country textboxes as well ( Here I am assuming that company name is unique). Let’s see how to do that using auto_complete plugin.

Before we start, you can find the entire sample source code at http://github.com/spritle/auto_complete_custom/tree/master
Lets make the basic stuff working first
form1
So lets have two models
1) user model
attributes: id, name, age, company_id
2)company model
attributes: id, name, address, state, country
So, once we have the models ready. Let’s generate the controller => user_controller with actions index, companies, create first later we need to add few more actions
Lets see index.rhtml source
[source language=”html”]


<%= stylesheet_link_tag "site" %>
<%= javascript_include_tag :defaults %>


<% form_for :user, :url => {:action => ‘create’} do |form| %>
Name:<%= form.text_field :name %>
Age:<%= form.text_field :age %>
Company name:<%= text_field_with_auto_complete :company, :name, {:size => 40},
{:url => ‘user/companies’, :method => ‘get’, :with => “‘search=’+element.value”} %>

Address:
State:
Country:

<%= submit_tag "Submit", :class => “submit” %>
<% end %>


[/source]
Let’s see what are the arguments that text_field_with_auto_complete taking. It takes company object, name of the method and rest of them were all options like url and so on. So we have to create an action companies in the controller and a page with list of companies (companies.rhtml)
First lets see the action in the controller companies
[source language=”Ruby”]
def companies
@companies = Company.find :all, :conditions => [‘name like ?’,”%#{params[:search]}%”]
end
[/source]
There is not much to explain in this action as it returns all the records based on the characters entered in the autocomplete textbox. ( If you dont have the condition it will list all the companies)
Now for the companies.rhtml view would look like
[source language=”Ruby”]
<%= auto_complete_result @companies, :name %>
[/source]
auto_complete_result which you can find it at vendor/plugins/auto_complete/lib/auto_complete_macros_helper.rb, which is a helper that returns an ul and li list of items (in this case it returns all companies in the list format).
To check this you can visit the companies.rhtml page go to the link http:///user/companies
view1
So thats all the basic steps.
Now let’s move to the next step that is when I select a company name from the list it should be able to fill the address,state and country fields automagically. For that we need to make few changes in index.rhtml first ( that is add Ajax.Request)
[source language=”Ruby”]
<%= text_field_with_auto_complete :company, :name, {:size => 40},
{:url => ‘user/companies’, :method => ‘get’,
:with => “‘search=’+element.value”,
:after_update_element =>
“function (ele, value){
new Ajax.Request(‘/user/data_loader/’ + value.innerHTML,{
asynchronous:true,
evalScripts:true,
parameters:’authenticity_token=’ + auth_token
});
return false;
}
“} %>
[/source]
In the above code we added a new option “:after_update_element“. It is an option for auto_complete plugin,
a JavaScript expression is called when the user has selected one of the proposed values. The expression should take two variables: element and value. Element is a DOM element for the field, value is the value selected by the user.
So value.innerHTML will have the selected company name and we are making an ajax call to the action data_loader in user_controller (which we need to write the logic).
Now there is little more tweaking necessary before we proceed. Your server expects an authenticity token from the ajax call you made, so you need to pass the authenticity token. Add this line in layout or in index.rhtml (inside of head tag)
[source language=”html”]
<%= javascript_tag "auth_token = '#{form_authenticity_token}';" %>
[/source]
So now auth_token variable will be available for JavaScript calls.
[source language = “javascript”]
parameters:’authenticity_token=’ + auth_token
[/source]
Lets see the logic for data_loader action in user_controller.rb file
[source language=”Ruby”]
def data_loader
@company = Company.find_by_name params[:id]
render :update do |page|
page.replace_html ‘preFillDiv’, :partial => ‘autocomplete_form’
end
end
[/source]
params[:id] will have the company name so we will try to get the record with that name (here we assume company name is unique)
Once we get that record we have to fill the company address,state and country in respective fields I am just replacing the div with a partial which has three text fields and the values inside it
See the partial _autocomplete_form.rhtml
[source language=”html”]
Address1: type=”text”>
State : type=”text”>
Country: type=”text”>
[/source]
Thats all folks. If you can hook this all together then you may see the stuff in action.
The source code for this application can be found at our GITHUB : auto_complete_custom repository as well. Do check it out and let us know your feedback.

Related posts:

5 Replies to “Advanced Auto Complete Feature (auto_complete ROR Plugin)”

  1. Thank you for this post.
    A quick question on this, if the company name is not on the list (i.e. it is one you have never heard of, will it add the new company too?

  2. What if the company name is not unuique. how do you get the unique id for the company. I am working on a similar thing, but it has to do with contacts. I need to pass the unique contact id to the forms method and also, i want to display only the contact name when the autocomplete throws the results. I have managed to display the list of contacts, but need ideas to pass the contact id to the method.
    Cheers!

  3. Yes here I dint worked on that part here, yes it is true in some scenarios company name is not unique. Let’s say Spritle is located in chennai as well as in Bangalore so my solution to this would be – When I list the companies on a keystroke I will provide this kind of list Spritle (Chennai) and Spritle (Bangalore) so when I select Spritle (chennai), I am passing these values to my action which I need to split the string in to company name and city name and based on that I will fill the other details in the text fields, hope I answered your question.

Leave a Reply

Your email address will not be published. Required fields are marked *