Ajax.InPlaceSelect + Ruby on Rails

The Scriptaculous Ajax.InPlaceSelect is very useful for simple data updates. Here's a little piece of code, based on the excellent editable_content helper.

def selectable_content(options)
options[:content] = { :element => 'span' }.merge(options[:content])
options[:url] = {}.merge(options[:url])
options[:ajax] ||= {}
script = Array.new
script << "new Ajax.InPlaceSelect("
script << " '#{options[:content][:options][:id]}',"
script << " '#{url_for(options[:url])}',"
script << " [" + options[:data][:collection].collect { |c| "'"+escape_javascript(c.send(options[:data][:value_method]).to_s)+"'" }.join(', ') + " ],"
script << " [" + options[:data][:collection].collect { |c| "'"+escape_javascript(c.send(options[:data][:text_method]).to_s)+"'" }.join(', ') + " ],"
script << " {"
script << options[:ajax].map{ |key, value| "#{key.to_s}: #{value}" }.join(", ")
script << " }"
script << ")"

content_tag(
options[:content][:element],
options[:content][:text],
options[:content][:options]
) + javascript_tag( script.join("\n") )
end

Use it like this:

<%= selectable_content(
:content => {
:text => cd.library.name,
:options => {
:id => "cd_library_id_#{cd.id}",
:class => 'editable-content'
}
},
:url => {
:controller => '/admin/cd',
:action => 'ajax_update_library_id',
:id => cd.id
},
:data => {
:collection => Library.find(:all, :order => 'name'),
:value_method => 'id',
:text_method => 'name'
}
) %>

Leave a Reply