Wayne Robinson in javascript, programming, ruby on rails
Ever wanted to extract multiple values from a Script.aculo.us Google Suggest-like autocomplete text field? I recently did and here's how.
If you aren't aware of how to use autocomplete text fields, please read over the simple and customised demos available at Script.aculo.us. Also, a warning, this demo utilises Ruby on Rails however, with a little bit of modification, this should work using the Script.aculo.us library without Ruby on Rails.
This example will auto-populate a state and postcode based on the user's selected suburb (yes, I'm Australian).
The first step is to create a view for the page containing the autocomplete field and for the autocomplete field itself.
Controller:
def new
# This is the main controller that will
# contain the autocomplete field
@contact = Contact.new
end
def auto_complete_for_suburb
suburb = params[:suburb]
@surburbs = Suburb.find_by_name(suburb,
:order => "name", :limit => 20)
render :partial => "auto_complete_suburb"
end
View for the new action (assume an application.rhtml template has been created, this template must include the Prototype and Script.aculo.us javascript libraries):
<%= form_tag({:action => :create}, {:method => :post}) %>
Name:
<%= text_field(:contact, :name) %>
Suburb:
<%= text_field_with_autcomplete(:contact, :suburb,
:select => "value",
:after_update_element =>
"function (ele, value) {
$("contact_state").value =
Ajax.Autocompleter.extract_value(value,
'STATE');
$("contact_postcode").value =
Ajax.Autocompleter.extract_value(value,
'POSTCODE'); }
") %>
State:
<%= text_field(:contact, :state, :size => 10) %>
Postcode:
<%= text_field(:contact, :postcode,
:size => 10) %>
<%= end_form_tag %>
Before we continue any further, it is worth-while defining the _auto_complete_suburb.rhtml partial.
<% unless @suburbs.nil? -%>
<% @suburbs.each do | suburb | -%>
<%= h("#{suburb[:name]}, #{suburb[:state]}" +
"#{suburb[:postcode]}") %>
<% end -%>
<% end -%>
The autocompleter view has three (3) hidden
You may also want to cast your eye over the suburb field definition in the new contact view as this is where most of the action is. There are two options to note:
- the :value option which specifies the class name of the element which contains the value to place in attribute (the default would be whatever is within the rendered field which, as we will find out below, will contain more than just the selected suburb)
- the :after_update_element option which specifies a piece of Javascript to execute when the item is selected. You will see that this Javascript executes the Ajax.Autocompleter.extract_value function twice. This function does not exist in Script.aculo.us but is provides an easy way to extract extra values from an autocomplete list.
The Script.aculo.us Autocompleter methods conviently pass the complete contents of the
Additional method for Ajax.Autocompleter class. This can be declared anywhere after the inital Script.aculo.us script inclusion. For my purposes I put this at the top of my application.js file.
Ajax.Autocompleter.extract_value =
function (value, className) {
var result;
var elements =
document.getElementsByClassName(className, value);
if (elements && elements.length == 1) {
result = elements[0].innerHTML.unescapeHTML();
}
return result;
};
So that's all there is to it. If anyone would like me to create a demo of the above code, ask me and, if I get enough requests, I'll put something together.
No comments:
Post a Comment