The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Fast Auto-completion with Rails, Scriptaculous and JSON

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Matthias Georgi

Posts: 54
Nickname: georgi
Registered: Apr, 2007

Matthias Georgi is a Ruby on Rails freelancer.
Fast Auto-completion with Rails, Scriptaculous and JSON Posted: Apr 4, 2007 9:43 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Matthias Georgi.
Original Post: Fast Auto-completion with Rails, Scriptaculous and JSON
Feed Title: Matthias Georgi
Feed URL: http://feeds.feedburner.com/matthias-georgi?format=xml
Feed Description: Webdev, Gamedev and Interaction Design.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Matthias Georgi
Latest Posts From Matthias Georgi

Advertisement
Inspired by the excellent Rails Recipes book , I created an improved Auto-completion helper, which uses JSON and AJAX instead of a script tag for loading the completions.

What we want to achieve is a search field, which pops up immediately, showing us a list of possible completions for our search word. Look at Google Suggest to get an idea.

Rails already has an auto_complete_field, which sends an AJAX request for each keystroke. This approach is quite slow, but works in most cases, especially for large datasets auto_complete_field is the better choice.

Our idea, stolen from the Rails Recipes book is to fetch the array of possible completions only once. Each keystroke will trigger only a local lookup and need no further server interaction. Scriptaculous already has the right tool for this job: Autocompleter.Local . We will just pass a javascript array of possible completions to the constructor and we're done.

OK, let's start. First we need the CSS used by Autocompleter.Local, which styles the choices box:
div.auto_complete {
width: 350px;
background: #fff;
}

div.auto_complete ul {
border:1px solid #888;
margin:0;
padding:0;
width:100%;
list-style-type:none;
}

div.auto_complete ul li {
margin:0;
padding:3px;
}


div.auto_complete ul li.selected {
background-color: #ffb;
}

div.auto_complete ul strong.highlight {
color: #800;
margin:0;
padding:0;
}

Rails already has an controller macro for generating a auto completion action. We will create a similar macro, which will generate an action, which in turn generates the JSON response. Sounds complex, but the implementation is quite easy:

def self.fast_auto_complete_for(object, method, options = {})
define_method("auto_complete_for_#{object}_#{method}") do
render :json => object.to_s.camelize.constantize.find(:all).map(&method).to_json
end
end



The response of the generated action will now contain a list of all values for the desired attribute. You can use it like:

fast_auto_complete_for :sport, :name

Now let us get into the tricky part: the javascript macro helper. How will we get the completion list? Prototype includes the Ajax.Request class, which sends an Ajax Request to our generated action and fetches the array encoded as JSON. Furthermore we have to generate a div which will hold the popup list for our completion entries. Without going into detail, I'll just show you the code:

def fast_auto_complete_field(field_id, options={})
div_id = "#{field_id}_auto_complete"
url = options.delete(:url) or raise "url required"
options = options.merge(:tokens => ',', :frequency => 0 )
markaby {
div.auto_complete(:id => div_id) {}
javascript_tag <<-end
new Ajax.Request('#{url}', {
method: 'get',
onSuccess: function(transport) {
new Autocompleter.Local('#{field_id}', '#{div_id}', eval(transport.responseText), #{options.to_json});
}
});
end
}
end

Note, that I use my simple markaby helper, which I presented in my last post. It is just a little more convenient not to do all this string concatenation. Our helper needs the id for the text field we want to enhance. Based on this id the helper generates the div for presenting the completion entries. It is also required to pass the url of the json action, which is in our case /sports/auto_complete_for_sport_name.

Usage example:

form {
input(:type => 'text', :name => 'name', :id => 'sport_name')
input(:type => 'submit', :value => 'Search')
}

fast_auto_complete_field :sport_name, :url => '/sports/auto_complete_for_sport_name'


Well, that's it. Now you may enjoy snappy auto-completion and feel good about using bleeding edge technology like AJAX and JSON.

By the way, I'm really having a hard time formatting my code snippets here. I use this syntax-highlighter , which just works, as the styles are directly encoded into the span tags. Unfortunately every edit opertion at blogger.com swallows some whitespaces,
which is quite annoying. Maybe somebody knows a better way to do this?

Read: Fast Auto-completion with Rails, Scriptaculous and JSON

Topic: A dialog box warns about &#8216;Inconsistent Line Endings' when I load some files. Previous Topic   Next Topic Topic: It had to happen: Ruby on Rails opinions from a PHP developer

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use