Autocomplete in Rails 3 with jQuery & jQuery UI

I’m in the process of building a Rails application and needed to introduce some autocomplete functionality on a couple of text fields.

If you’re using Rails 3 and are not working with jQuery and the jQuery UI library, then there is a solid gem you may want to checkout; otherwise, here’s how you can setup autocomplete on a text field using Rails 3, jQuery, and jQuery UI.

First, make sure to properly include the jQuery UI stylesheets and JavaScript sources in the related layouts:

<%= stylesheet_link_tag "reset", "layout", "themes/base/jquery.ui.all" %>
<%= javascript_include_tag "jquery.ui.core", "jquery.ui.widget", "jquery.ui.position", "jquery.ui.autocomplete" %>

Next, locate the controller action that will load the collection used to populate the autocomplete field. For me, I was using both new and edit.

Specifically, I wanted to load all of the locations associated with each contact in the system.

Since locations aren’t required fields in the rest of the application, I also needed to remove the empty entries from the collection hence the need for compact and reject.

def new
	# Irrelevant code snipped
	@locations = Contact.all.map(&:location).compact.reject(&:blank?)
end

Because this particular action will be called for both synchronous and asynchronous requests, I needed to introduce two handles for the response.

Specifically, the action will serve the HTML view whenever the browser accesses the page and will return the JS view when for ajax requests:

def new
	# Irrelevant code snipped
	@locations = Contact.all.map(&:location).compact.reject(&:blank?)
	respond_to do |format|
		format.html
		format.js
	end
end

After that, I added a view – new.js.erb – to respond to the ajax request. It’s purpose is to simply return the raw collection:

<%= raw @locations %>

Finally, I hooked up the text field to the newly created view by adding the following code to application.js. Simply put, this displays an autocomplete list for the text field having the ID of contact_location:

$(function() {

	$('#contact_location').autocomplete({
		source: '/contacts/new.js'
	});

});

Again, I recommend this route only if you’re already using jQuery and it’s UI library within the context of your project; otherwise, sticking with a gem may be a better option.

9 Comments

I really need to come up with a project I can build in Rails.

That is all.

    To Do Lists, Note Taker, Contact Manager, Event Registration System, etc.

    Just go for something – odds are, the first thing you build won’t be the most practical thing but it gets your feet wet :).

Hmmm, Good suggestions. I shall continue to ponder.

Hi, I am attempting this in rails 3.2 with no success. In my application layout file I’ve got:

In my new.html.erb I’ve got:

{ :multipart => true }, remote: true do |f| %>

In my new.js.erb I’ve got:

In my application.js I’ve put at the bottom:

$(function() {

$(‘#aidmodel_brand’).autocomplete({
source: ‘/aidmodels/new.js’
});

});

And, lastly, here is my controller:

def new
@aidmodel = Aidmodel.new
@brands = Aidmodel.all.map(&:brand).compact.reject(&:blank?)
respond_to do |format|
format.html
format.js
end
end

Thanks!!

Innocent Akhidenor October 7, 2012 at 9:54 am

pls can you paste your view for your new method..ie where your autocomplete form is

thanks

    This particular post was based on a contract project that I was working on at the time. I’m not longer working on that particular project nor have access to the codebase, so I unfortunately can’t offer much.

    That said, I can recommend that you create a input element, and make sure that the ID of the element matches what’s specified in the JavaScript, and you should be good to go.

    If not, double-check your developer tools console – it should provide an explanation as to what’s up.

Your post help me get started, but I had to figure out how to finish this example. First, the JQuery autcomplete source as URL string expects a JSON list of options, so you really should use a URL like “/contacts/new.json”. Then, your Rails controller should respond_to format.json {:json => @contacts.map {|contact| {:label => contact.name, :value => contact.id}}}.

Also, your new.js.erb probably would present problems, because JQuery autocomplete is expecting a JSON formatted list, or list of {label: , value:} pairs. You don’t need any template with the respond_to clause above.

Leave a Reply

Name and email address are required. Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>