JSON.Autocompleter gives you a hybrid text/select HTML input widget that fetches the possible list of values from a remote JSON source.
In other words, with a JSON.Autocompleter widget the user can either start typing what they’re looking for, or they can click a list pulldown.
TODO:
-
Occassional display glitches (some possible cross-browser compatibility issues, etc.)
-
The Autocompleter initializer should be more customizable (for example, we might want to set a custom URL for the list pulldown image).
-
Code needs to be cleaned up…
Install as a plugin into your Rails app:
ruby script/plugin install git://github.com/zuk/json_autocompleter.git
The required scripts, stylesheets, and images will be copied automatically into your /public folder during the install.
JSON.Autocompleter is based on the script.aculo.us Autocompleter. This is packaged with Rails, so all you have to do is make sure the following scripts are loaded in your page:
<%= javascript_include_tag 'controls', 'json2', 'json_autocompleter' %>
Also don’t forget to link to the auto_complete.css stylesheet:
<%= stylesheet_link_tag 'auto_complete' %>
Set up the widget:
<%= json_autocomplete(@lunch, :meat, meats_url) %>
Or if you want to get more fancy:
<%= json_autocomplete(@lunch, :meat, meats_url, :width => '30em', :label_attribute => :description, :with_form_elements => ['category_id']) %>
Write a Rails controller to return the JSON data:
controller Meats < ApplicationController # GET /meats.json def index @meats = Meat.find(:all) respond_to do |format| format.json { render :json => @meats } end end end
The string returned by your model’s to_s method will be used as the option label, so implement this to customize the output (in the future the script will be modified to allow for a custom field name to be used).
The JSON data returned by your controller action should look something like this:
[{"meat": {"id": 1, "name": "Salami"}}, {"meat": {"id": 2, "name": "Ham"}}, {"meat": {"id": 3, "name": "Hot Dog"}}]
Or this will work too:
[{"id": 1, "name": "Salami"}, {"id": 2, "name": "Ham"}, {"id": 3, "name": "Hot Dog"}]
If instead of “name” you want to use some other attribute or method, specify it in the helper under the :label_attribute option, like so:
<%= json_autocomplete(@lunch, :meat, meats_url, :label_attribute => :to_s) %>
The corresponding JSON data should look like this:
[{"meat": {"id": 1, "to_s": "Salami"}}, {"meat": {"id": 2, "to_s": "Ham"}}, {"meat": {"id": 3, "to_s": "Hot Dog"}}]
Copyright © 2009 Matt Zukowski, released under the MIT license