Skip to content

Commit

Permalink
Added grouped_options_for_select helper method for wrapping option ta…
Browse files Browse the repository at this point in the history
…gs in optgroups. [#977 state:resolved]

Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
  • Loading branch information
JonCrawford authored and lifo committed Jan 29, 2009
1 parent 306cc2b commit 8761663
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 0 deletions.
2 changes: 2 additions & 0 deletions actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*2.3.0 [Edge]*

* Added grouped_options_for_select helper method for wrapping option tags in optgroups. #977 [Jon Crawford]

* Implement HTTP Digest authentication. #1230 [Gregg Kellogg, Pratik Naik] Example :

class DummyDigestController < ActionController::Base
Expand Down
56 changes: 56 additions & 0 deletions actionpack/lib/action_view/helpers/form_options_helper.rb
Expand Up @@ -277,6 +277,62 @@ def option_groups_from_collection_for_select(collection, group_method, group_lab
end
end

# Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
# wraps them with <tt><optgroup></tt> tags.
#
# Parameters:
# * +grouped_options+ - Accepts a nested array or hash of strings. The first value serves as the
# <tt><optgroup></tt> label while the second value must be an array of options. The second value can be a
# nested array of text-value pairs. See <tt>options_for_select</tt> for more info.
# Ex. ["North America",[["United States","US"],["Canada","CA"]]]
# * +selected_key+ - A value equal to the +value+ attribute for one of the <tt><option></tt> tags,
# which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
# as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
# * +prompt+ - set to true or a prompt string. When the select element doesn’t have a value yet, this
# prepends an option with a generic prompt — "Please select" — or the given prompt string.
#
# Sample usage (Array):
# grouped_options = [
# ['North America',
# [['United States','US'],'Canada']],
# ['Europe',
# ['Denmark','Germany','France']]
# ]
# grouped_options_for_select(grouped_options)
#
# Sample usage (Hash):
# grouped_options = {
# 'North America' => [['United States','US], 'Canada'],
# 'Europe' => ['Denmark','Germany','France']
# }
# grouped_options_for_select(grouped_options)
#
# Possible output:
# <optgroup label="Europe">
# <option value="Denmark">Denmark</option>
# <option value="Germany">Germany</option>
# <option value="France">France</option>
# </optgroup>
# <optgroup label="North America">
# <option value="US">United States</option>
# <option value="Canada">Canada</option>
# </optgroup>
#
# <b>Note:</b> Only the <tt><optgroup></tt> and <tt><option></tt> tags are returned, so you still have to
# wrap the output in an appropriate <tt><select></tt> tag.
def grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil)
body = ''
body << content_tag(:option, prompt, :value => "") if prompt

grouped_options = grouped_options.sort if grouped_options.is_a?(Hash)

grouped_options.each do |group|
body << content_tag(:optgroup, options_for_select(group[1], selected_key), :label => group[0])
end

body
end

# Returns a string of option tags for pretty much any time zone in the
# world. Supply a TimeZone name as +selected+ to have it marked as the
# selected option tag. You can also supply an array of TimeZone objects
Expand Down
26 changes: 26 additions & 0 deletions actionpack/test/template/form_options_helper_test.rb
Expand Up @@ -143,6 +143,32 @@ def test_option_groups_from_collection_for_select
)
end

def test_grouped_options_for_select_with_array
assert_dom_equal(
"<optgroup label=\"North America\"><option value=\"US\">United States</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"Europe\"><option value=\"GB\">Great Britain</option>\n<option value=\"Germany\">Germany</option></optgroup>",
grouped_options_for_select([
["North America",
[['United States','US'],"Canada"]],
["Europe",
[["Great Britain","GB"], "Germany"]]
])
)
end

def test_grouped_options_for_select_with_selected_and_prompt
assert_dom_equal(
"<option value=\"\">Choose a product...</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>",
grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], "Cowboy Hat", "Choose a product...")
)
end

def test_optgroups_with_with_options_with_hash
assert_dom_equal(
"<optgroup label=\"Europe\"><option value=\"Denmark\">Denmark</option>\n<option value=\"Germany\">Germany</option></optgroup><optgroup label=\"North America\"><option value=\"United States\">United States</option>\n<option value=\"Canada\">Canada</option></optgroup>",
grouped_options_for_select({'North America' => ['United States','Canada'], 'Europe' => ['Denmark','Germany']})
)
end

def test_time_zone_options_no_parms
opts = time_zone_options_for_select
assert_dom_equal "<option value=\"A\">A</option>\n" +
Expand Down

1 comment on commit 8761663

@al2o3cr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve got a version of the nested array part of this grafted into options_for_select so that form.select calls can get some optgroup love – would it still be useful to submit it?

Please sign in to comment.