• Stars
    star
    926
  • Rank 49,328 (Top 1.0 %)
  • Language
    Ruby
  • License
    MIT License
  • Created over 14 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An easy and unobtrusive way to use jQuery's autocomplete with Rails 3

Project Moved

There has been some confusion around the naming as to where to find the Rails4 version of this gem due to the original naming. With the latest release I have taken the opportunity to address this by moving the official repo.

The official repo is now located at rails-jquery-autocomplete

rails3-jquery-autocomplete

Build Status Gem Version

An easy way to use jQuery's autocomplete with Rails 3.

Supports both ActiveRecord, mongoid, and MongoMapper.

Works with Formtastic and SimpleForm

ActiveRecord

You can find a detailed example on how to use this gem with ActiveRecord here.

MongoID

You can find a detailed example on how to use this gem with MongoID here. (Same thing, different branch)

Before you start

Make sure your project is using jQuery-UI and the autocomplete widget before you continue.

You can find more info about that here:

I'd encourage you to understand how to use those 3 amazing tools before attempting to use this gem.

Installing

Include the gem on your Gemfile

gem 'rails3-jquery-autocomplete'

Install it

bundle install

Rails 3.0.x

Run the generator

rails generate autocomplete:install

And include autocomplete-rails.js on your layouts

javascript_include_tag "autocomplete-rails.js"

Upgrading from older versions

If you are upgrading from a previous version, run the generator after installing to replace the javascript file.

rails generate autocomplete:install

I'd recommend you do this every time you update to make sure you have the latest JS file.

Uncompressed Javascript file

If you want to make changes to the JS file, you can install the uncompressed version by running:

rails generate autocomplete:uncompressed

Rails 3.1.x and higher

Just add it to your app/assets/javascripts/application.js file

//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require autocomplete-rails

Usage

Model Example

Assuming you have a Brand model:

class Brand < ActiveRecord::Base
end

create_table :brand do |t|
  t.column :name, :string
end

Controller

To set up the required action on your controller, all you have to do is call it with the class name and the method as in the following example:

class ProductsController < Admin::BaseController
  autocomplete :brand, :name
end

This will create an action autocomplete_brand_name on your controller, don't forget to add it on your routes file

resources :products do
  get :autocomplete_brand_name, :on => :collection
end

Options

:full => true

By default, the search starts from the beginning of the string you're searching for. If you want to do a full search, set the full parameter to true.

class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :full => true
end

The following terms would match the query 'un':

  • Luna
  • Unacceptable
  • Rerun

:full => false (default behavior)

Only the following terms mould match the query 'un':

  • Unacceptable

:limit => 10 (default behavior)

By default your search result set is limited to the first 10 records. This can be overridden by specifying the limit option.

:extra_data

By default, your search will only return the required columns from the database needed to populate your form, namely id and the column you are searching (name, in the above example).

Passing an array of attributes/column names to this option will fetch and return the specified data.

class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :extra_data => [:slogan]
end

:display_value

If you want to display a different version of what you're looking for, you can use the :display_value option.

This options receives a method name as the parameter, and that method will be called on the instance when displaying the results.

class Brand < ActiveRecord::Base
  def funky_method
    "#{self.name}.camelize"
  end
end


class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :display_value => :funky_method
end

In the example above, you will search by name, but the autocomplete list will display the result of funky_method

This wouldn't really make much sense unless you use it with the "id_element" attribute. (See below)

Only the object's id and the column you are searching on will be returned in JSON, so if your display_value method requires another parameter, make sure to fetch it with the :extra_data option

:hstore

Added option to support searching in hstore columns.

Pass a hash with two keys: :method and :key with values: the hstore field name and the key of the hstore to search.

e.g autocomplete :feature, :name, :hstore => {:method => 'name_translations', :key => 'en'}

:scopes

Added option to use scopes. Pass scopes in an array. e.g :scopes => [:scope1, :scope2]

:column_name

By default autocomplete uses method name as column name. Now it can be specified using column_name options :column_name => 'name'

json encoder

Autocomplete uses Yajl as JSON encoder/decoder, but you can specify your own

class ProductsController < Admin::BaseController
  autocomplete :brand, :name do |items|
     CustomJSON::Encoder.encode(items)
  end
end

View

On your view, all you have to do is include the attribute autocomplete on the text field using the url to the autocomplete action as the value.

form_for @product do |f|
  f.autocomplete_field :brand_name, autocomplete_brand_name_products_path
end

This will generate an HTML tag that looks like:

<input type="text" data-autocomplete="products/autocomplete_brand_name">

If you are not using a FormBuilder (form_for) or you just want to include an autocomplete field without the form, you can use the autocomplete_field_tag helper.

form_tag 'some/path'
  autocomplete_field_tag 'address', '', address_autocomplete_path, :size => 75
end

Multiple Values Separated by Delimiter

To generate an autocomplete input field that accepts multiple values separated by a given delimiter, add the 'data-delimiter' and :multiple options:

form_for @product do |f|
  f.autocomplete_field :brand_names, autocomplete_brand_name_products_path,
  'data-delimiter' => ',', :multiple => true
end

NOTE: Setting the :multiple option to true will result in the chosen values being submitted as an array. Leaving this option off will result in the values being passed as a single string, with the values separated by your chosen delimiter.

Automatically focus on the first autocompleted item

To have the first item be automatically focused on when the autocomplete menu is shown, add the 'data-auto-focus' option and set it to true.

form_for @product do |f|
	f.autocomplete_field :brand_names, autocomplete_brand_name_products_path,
	'data-auto-focus' => true
end

Now your autocomplete code is unobtrusive, Rails 3 style.

Getting the object id

If you need to use the id of the selected object, you can use the id_element attribute too:

f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :id_element => '#some_element'

This will update the field with id *#some_element with the id of the selected object. The value for this option can be any jQuery selector.

Changing destination element

If you need to change destination element where the autocomplete box will be appended to, you can use the :append_to option which generates a data-append-to HTML attribute that is used in jQuery autocomplete as append_to attribute.

The :append_to option accepts a string containing jQuery selector for destination element:

f.autocomplete_field :product_name, '/products/autocomplete_product_name', :append_to => "#product_modal"

The previous example would append the autocomplete box containing suggestions to element jQuery('#product_modal'). This is very useful on page where you use various z-indexes and you need to append the box to the topmost element, for example using modal window.

Sending extra search fields

If you want to send extra fields from your form to the search action, you can use the :fields options which generates a data-autocomplete-fields HTML attribute.

The :fields option accepts a hash where the keys represent the Ajax request parameter name and the values represent the jQuery selectors to retrieve the form elements to get the values:

f.autocomplete_field :product_name, '/products/autocomplete_product_name', :fields => {:brand_id => '#brand_element', :country => '#country_element'}

class ProductsController < Admin::BaseController
  def autocomplete_product_name
    term = params[:term]
    brand_id = params[:brand_id]
    country = params[:country]
    products = Product.where('brand = ? AND country = ? AND name LIKE ?', brand_id, country, "%#{term}%").order(:name).all
    render :json => products.map { |product| {:id => product.id, :label => product.name, :value => product.name} }
  end
end

Getting extra object data

If you need to extra data about the selected object, you can use the :update_elements HTML attribute.

The :update_elements attribute accepts a hash where the keys represent the object attribute/column data to use to update and the values are jQuery selectors to retrieve the HTML element to update:

f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :update_elements => {:id => '#id_element', :slogan => '#some_other_element'}

class ProductsController < Admin::BaseController
  autocomplete :brand, :name, :extra_data => [:slogan]
end

The previous example would fetch the extra attribute slogan and update jQuery('#some_other_element') with the slogan value.

Running custom code on selection

A javascript event named railsAutocomplete.select is fired on the input field when a value is selected from the autocomplete drop down. If you need to do something more complex than update fields with data, you can hook into this event, like so:

$('#my_autocomplete_field').bind('railsAutocomplete.select', function(event, data){
  /* Do something here */
  alert(data.item.id);
});

Formtastic

If you are using Formtastic, you automatically get the autocompleted_input helper on semantic_form_for:

semantic_form_for @product do |f|
  f.input :brand_name, :as => :autocomplete, :url => autocomplete_brand_name_products_path
end

The only difference with the original helper is that you must specify the autocomplete url using the :url option.

SimpleForm

If you want to use it with simple_form, all you have to do is use the :as option on the input and set the autocomplete path with the :url option.

simple_form_for @product do |form|
  form.input :name
  form.input :brand_name, :url => autocomplete_brand_name_products_path, :as => :autocomplete

Cucumber

I have created a step to test your autocomplete with Cucumber and Capybara, all you have to do is add the following lines to your env.rb file:

require 'cucumber/autocomplete'

Then you'll have access to the following step:

I choose "([^"]*)" in the autocomplete list

An example on how to use it:

@javascript
Scenario: Autocomplete
  Given the following brands exists:
    | name  |
    | Alpha |
    | Beta  |
    | Gamma |
  And I go to the home page
  And I fill in "Brand name" with "al"
  And I choose "Alpha" in the autocomplete list
  Then the "Brand name" field should contain "Alpha"

I have only tested this using Capybara, no idea if it works with something else, to see it in action, check the example app.

Steak

I have created a helper to test your autocomplete with Steak and Capybara, all you have to do is add the following lines to your acceptance_helper.rb file:

require 'steak/autocomplete'

Then you'll have access to the following helper:

choose_autocomplete_result

An example on how to use it:

scenario "Autocomplete" do
  lambda do
    Brand.create! [
      {:name => "Alpha"},
      {:name => "Beta"},
      {:name => "Gamma"}
    ]
  end.should change(Brand, :count).by(3)

  visit home_page
  fill_in "Brand name", :with => "al"
  choose_autocomplete_result "Alpha"
  find_field("Brand name").value.should include("Alpha")
end

I have only tested this using Capybara, no idea if it works with something else.

Development

If you want to make changes to the gem, first install bundler 1.0.0:

gem install bundler

And then, install all your dependencies:

bundle install

Running the test suite

You need to have an instance of MongoDB running on your computer or all the mongo tests will fail miserably.

To run all the tests once, simply use

rake test

while you're developing, it is recommended that you run

bundle exec guard

to have the relevant test run every time you save a file.

Integration tests

If you make changes or add features to the jQuery part, please make sure you write a cucumber test for it.

You can find an example Rails app on the integration folder.

You can run the integration tests with the cucumber command while on the integration folder:

cd integration
rake db:migrate
cucumber

Where to test what

If you're making or tweaking a plugin (such as the formtastic plugin or simple_form plugin), check out the simple_form_plugin_test for an example of how to test it as part of the main rake test run. Historically, plugins like these had been tested (shoddily) as part of the integration tests. Feel free to remove them from the integration suite and move them into the main suite. Your tests will run much faster, and there will be less likelihood of your feature breaking in the future. Thanks!

Thanks to

Everyone on this list

About the Author

Crowd Interactive is an American web design and development company that happens to work in Colima, Mexico. We specialize in building and growing online retail stores. We don’t work with everyone – just companies we believe in. Call us today to see if there’s a fit. Find more info here!

More Repositories

1

acts_as_shopping_cart

Simple Shopping Cart implementation, Official repo: https://github.com/dabit/acts_as_shopping_cart
Ruby
257
star
2

rails3-jquery-autocomplete-app

This app is meant to show you how to use the rails3-jquery-autocomplete gem.
Ruby
90
star
3

blog.crowdint.com

Crowd Interactive Tech blog
Ruby
54
star
4

slim_assets

Use Slim with Rails helpers in the asset pipeline
Ruby
29
star
5

fundraiser

Mountable Engine to set up a Crowdfunding app. Uses Amazon Simplepay to collect payments.
Ruby
25
star
6

blog.crowdint.com-jekyll

Crowd Interactive's tech blog
Ruby
24
star
7

prdashboard

CSS
22
star
8

slugoid

Drop-in solution to pretty urls when using Mongoid
Ruby
20
star
9

emojimenu

An Android Library that allows you to easily add emoji support to your Android application
Java
17
star
10

grpc-twitter-example

Example usage of grpc-go
Go
17
star
11

crowdblog

Generic blog engine we use for our blog style websites. Use at own risk
Ruby
12
star
12

acts_as_shopping_cart_app

Example app for acts_as_shopping_cart_gem
Ruby
10
star
13

fundraiser-app

Example app that uses fundraiser gem to create a crowdfunding site
Ruby
10
star
14

keyword_ranking

Ruby library to get the ranking of a url based on a keyword in Bing, Yahoo or Google
Ruby
9
star
15

facturacion_electronica

Ruby
7
star
16

easy-automation

Friendly Automation Testing Framework
Ruby
6
star
17

bamboohr

Consume BambooHR's API with Ruby
Ruby
5
star
18

vagrant-setup

Vagrant / Chef recipes to set up a new dev environment
Ruby
5
star
19

crudspec

Generate specs for CRUD controllers
Ruby
5
star
20

spree_conekta

Ruby
5
star
21

auditrail

Ruby
5
star
22

heroku_mongoid

Easy Mongoid on Heroku
Ruby
4
star
23

gransak

Go
4
star
24

pair-stations

Ruby
4
star
25

rankstar

Ruby gem used to get the ranking of a url based on a keyword in Bing, Yahoo or Google
Ruby
4
star
26

spree_brightpearl

Spree extension for BrightPearl connection
Ruby
3
star
27

associate_by

Allows you to associate two objects using a specified field.
Ruby
3
star
28

spree_store_locator

Store Locator for Spree
Ruby
3
star
29

Doku

Small Mac Os App that keeps track of your Google Docs
Ruby
2
star
30

spree-wrap

Consume a compatible Spree API from Ruby Motion
Ruby
2
star
31

ajax-nested-fields

Ruby
2
star
32

styleguide-deprecated

Create a base styleguide
Ruby
2
star
33

gopher-spree-api

Go
2
star
34

LearningIPhoneMotionExamples

Learning iPhone Programming Ruby Motion examples
Ruby
2
star
35

spree_reviews_rating

Ruby
2
star
36

destroyer

Ruby
2
star
37

rankit

Post stuff, rank it, let others rank, comment
Ruby
1
star
38

pomonit

Pomodoro monitor
Ruby
1
star
39

cucumber-debug

Launch a browser snapshot for cucumber failed scenarios
Ruby
1
star
40

scorecards

Score Cards
Ruby
1
star
41

rspechan_worker

Ruby
1
star
42

memphis

Rails.mx maintenance page
Ruby
1
star
43

find_method

Find a method on a class or an instance using part of the name
Ruby
1
star
44

ruby_on_rails_grupo_1

App que hemos desarrollado en el grupo 1 de los talleres de RoR
Ruby
1
star
45

crowdqna

Q & A Forum we use to get anonymous employee feedback
Ruby
1
star
46

sinatra-view-helpers

Integrates Rails View Helpers in Sinatra
Ruby
1
star
47

spree-mail-chimp

Ruby
1
star
48

hello_mail

Add a rake task to test your mail configuration on Rails 3
Ruby
1
star
49

ci_culture

Ruby
1
star
50

jPlaylist

JavaScript
1
star
51

rpx_regexp

Restrict who authenticates through Janrain with a regexp
Ruby
1
star
52

spree_shipworks

Ruby
1
star
53

simple_caches

Counter caches, as simple as you can imagine
Ruby
1
star
54

harry

VERY lightweight Ruby web applications framework
Ruby
1
star
55

gappster

Quick solution for Rails to authenticate your users with Google Apps' Open Id
Ruby
1
star
56

crowdousel

Small HTML script we use on our public screens
JavaScript
1
star
57

voting_engine

Ruby
1
star
58

mapit

Very, very simple gem that provides a helper to show a map of the specified address using Google Maps.
Ruby
1
star
59

sasha

Add your current Git SHA to your Rails app response headers
Ruby
1
star
60

jfloatable

jfloatable is a jQuery plugin allows you to have floating elements within an area, with a smooth and customizable movement when the window is scrolled. The advantage of using jfloatable is the freedom of move your elements within a container as the page scroll, perfect for content that you want to be visible at all time. It's so easy to install and configure you'll have it working on your site in minutes! Just keep reading and find out how!
JavaScript
1
star
61

magic_form

Ruby
1
star
62

hooker

Rack app to manage your git POST hooks
Ruby
1
star