Peter T Bosse II
2006-Feb-27 22:57 UTC
[Rails] Example code for select_from_db (a.k.a. combo box)
I''m not asking for help this time! :) :) In almost every Rails
project I create, I find that I want a select() popup menu that is
pre-populated by data from the database. Also, I want an "Other..."
option that presents a text_field_tag to input another (not
presented) option (basically a combo-box). In an attempt to be as
DRY as possible, I''ve come up with the following code for achieving
that. It works for me, but I wanted to see if any of y''all have any
commentary on how this could be better done (and also I wish I could
have found this when I was looking myself as an example of how this
could be done, so here it is for others).
- Peter
P.S. My model is Asset and controller is Assets (obviously), change
those instances below for your own model/controller names.
==== app/helpers/application_helper.rb ===
def select_from_db(object, method, choices, options = {},
html_options = {})
results = Asset.find(:all) if choices.blank?
if results
choices = Array.new
results.each do |result|
unless result.send(method).blank?
choices << result.send(method)
end
end
choices = choices.sort.uniq
end
choices.insert(0,"") if options[:include_blank]
choices << ["Other...","other"] if
options[:include_other]
if options[:selected]
selected = "#{options[:selected]}"
else
selected = ""
end
uniqid = "#{html_options[:uniqid]}" if html_options[:uniqid]
tag = "#{object}_#{method}_#{uniqid}"
output = Array.new
output << tag(''div'',
options { :open => true },
html_options { :id => "#{tag}_div" })
output << select_tag("#{tag}",
options_for_select( choices, selected ))
output << observe_field("#{tag}",
:condition => "escape(value) != ''''",
:url =>
{
:field => :select,
:action => :updateform,
:object => "#{object}",
:method => "#{method}",
:uniqid => "#{uniqid}"
},
:with => "''value=''+escape(value)")
output << content_tag(''span'', '''',
html_options { :id => "#{tag}_status" })
output << "</div>"
output << tag(''div'',
html_options { :style => ''display: none;'',
:id => "#{tag}_other_div" })
output << text_field_tag("#{tag}_other",
'''')
output << observe_field("#{tag}_other",
:condition => "escape(value) != ''''",
:url =>
{
:field => :other,
:action => :updateform,
:object => "#{object}",
:method => "#{method}",
:uniqid => "#{uniqid}"
},
:with => "''value=''+escape(value)")
output << content_tag(''span'', '''',
html_options = { :id => "#{tag}_other_status" })
output << "</div>"
end
==== app/controllers/assets_controller.rb ===
def updateform
case params[:field]
when "select"
case params[:value]
when "other"
render :partial => "show_other", :locals => { :params
=>
@params }
else
render :partial => "hide_other", :locals => { :params
=>
@params }
end
when "other"
render :partial => "hide_other", :locals => { :params
=>
@params }
end
end
==== app/views/assets/_show_other.rjs ===
tag = "#{params[:object]}_#{params[:method]}_#{params[:uniqid]}"
page << "if (Element.visible(''#{tag}_other_div'') ==
false)
Effect.SlideDown(''#{tag}_other_div'');"
page << "$(''#{tag}_other'').focus();"
page << "$(''submit'').disabled = true;"
==== app/views/assets/_hide_other.rjs ===
tag = "#{params[:object]}_#{params[:method]}_#{params[:uniqid]}"
if (params[:field] == "other")
page.insert_html :bottom, "#{tag}", content_tag("option",
"#{params
[:value]}")
page << "$(''#{tag}'').selectedIndex =
$(''#{tag}'').length-1;"
end
page << "if (Element.visible(''#{tag}_other_div''))
Effect.SlideUp(''#
{tag}_other_div'');"
page << "$(''submit'').disabled = false;"
==== app/views/assets/test.rhtml ===
<%=
select_from_db(''asset'',''head'','''',
options = { :include_blank =>
true, :include_other => true}, html_options = { :uniqid => "48"
}) %>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2392 bytes
Desc: not available
Url :
http://wrath.rubyonrails.org/pipermail/rails/attachments/20060227/c47895ab/smime.bin
Seemingly Similar Threads
- Updater and PeriodicUpdater fighting with one another
- importing files, columns "invade next column"
- Confusion with Converting Factors to Dates using as.date
- read.table() can't read in this table (But Splus can) (PR#9687)
- problem using "by" with custom function?
