Posted by Vamsi Krishna on December 3rd, 2009

In my previous blog on ‘Advanced Auto Complete’, I mentioned about how to pre-fill the fields upon selecting a company name for a person along with auto_complete feature (please have a quick look before looking in to this blog). In the previous solution we are getting results of companies (as a LI list of company names) based on the character you typed but, what if the company name is not unique ?. Let’s look at a simple example, Thought Works company is located in Chennai as well as in Bangalore, so I want differentiate both of them and I want to pre-fill the company details accordingly.

Here is the sample UI that I want to implement. As you can see Thought Works is repeated.
autocomplete1

If you are interested in knowing how it is implemented you can continue reading or if you just want the solution then please visit http://github.com/spritle/auto_complete_custom/tree/master

Now we have to get company name + city name in the list instead of just company name

So lets write a method (combined_name) in company model which will give you company name + address2

  def combined_name
    "#{name} - #{address2}"
  end

Now we will modify our companies view file

<%= auto_complete_result @companies, :combined_name %>

I hope the above solution works without further adjustment, but you need to do a minor tweaking here to make your solution work. Either you can use the modified auto_complete plugin from http://github.com/spritle/auto_complete ;) or you can modify auto_complete_macros_helper file in auto_complete plugin.

  def auto_complete_result(entries, field, phrase = nil)
    #return unless entries
    #items = entries.map { |entry| content_tag("li", phrase ? highlight(entry[field], phrase) : h(entry[field]))}
    #content_tag("ul", items.uniq)

    #Modified code
    items = []
    entries.each do |entry|
    	items << content_tag("li", phrase ? highlight(entry.send field, phrase) : h(entry.send field))
    end
    content_tag("ul", items.uniq)
  end

You just override the existing method auto_complete_result in auto_complete_macros_helper file with the above code.

Let me first explain why auto_complete didn’t work and then I will tell you how it can be fixed.

The first three lines of code is original auto_complete_result method, entries is an array of hashes.

[#<Company id: 1, name: "Spritle Software", address1: "Mogapair", address2: "Chennai, Tamilnadu", country: "India.", created_at: "2009-12-03 07:02:13", updated_at: "2009-12-03 07:02:13">, #<Company id: 2, name: "Thought Works", address1: "Guindy", address2: "Chennai, Tamilnadu", country: "India.", created_at: "2009-12-03 07:02:13", updated_at: "2009-12-03 07:02:13">, #<Company id: 4, name: "Thought Works", address1: "Airport Road", address2: "Bangalore, Karnataka", country: "India.", created_at: "2009-12-03 07:02:13", updated_at: "2009-12-03 07:02:13">]

and this is how it looks when you give

<%= auto_complete_result @companies, :name %>

it will work for name, but when you give combined_name it wont work because combined_name is not generated in the above array, combined_name is an instance method of Company mode(class). So you have to access it through Company object only, so this is how you can call it.

company = Company.first
1) company.combined_name
OR
2) company.send combined_name

Here we can use second type to call a method since field is a string.So, this is how we are calling in the above code

entry.send field

Now the final part,

 #user_controller file
  def data_loader
    str_tokens = params[:id].split("-")
    @company = Company.find_by_name_and_address2(str_tokens[0].rstrip,str_tokens[1].lstrip)

    render :update do |page|
      page.replace_html 'preFillDiv', :partial => 'autocomplete_form'
    end
  end

params[:id] will have combined name (company name + adderss2) so, you have to split it and based on the company name and address2 you can get the correct row.

Here I made an assumption that company name + address2 is unique, you can combine any number of fields you want and you have to get the proper company row with that information.

I hope this blog is useful.Please post any questions,feedback or any improvements in the comments section.

pixelstats trackingpixel Tags: , , ,
Unique Views: 392 Total views: 542
Follow responses at RSS 2.0. Leave a response | Trackback.

4 Responses to “Advanced Auto Complete Feature - Part 2”

  1. Interesting implementation! I will be using some ideas at my website, in the admin interface.

  2. Thank you,glad you like it. If you need any help please contact us.

  3. Adrian says:

    Great Blog, thanks. Have used information here to solve a problem I had retrieving the ID and duplicate rows in the search criteria.

  4. Hilman Zaky says:

    awesome..

    actually I had a User model to find with auto_complete plugin, which each user had a profile image (the image that I was implement is using Paperclip plugin). So I want to display both username and profile image, and lucky I found this blog.

    this is my implementation :

    # in model
    def combine_login_profile
    “#{login} - ”
    end

    # in auto_complete_macros_helper.rb
    # i just removed “h” on h(entry.send field)
    def auto_complete_result(entries, field, phrase = nil)
    items = []
    entries.each do |entry|
    items << content_tag(”li”, phrase ? highlight(entry.send field, phrase) : (entry.send field))
    end
    content_tag(”ul”, items.uniq)
    end

    Big Thanks..

    Leave a Reply