mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
added support for html attributes in options_for_select [#2165]
Signed-off-by: José Valim <jose.valim@gmail.com>
This commit is contained in:
parent
fc2480a277
commit
2dc1402417
2 changed files with 81 additions and 2 deletions
|
@ -270,6 +270,15 @@ module ActionView
|
|||
# options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
|
||||
# <option selected="selected">VISA</option>\n<option>MasterCard</option>\n<option selected="selected">Discover</option>
|
||||
#
|
||||
# You can optionally provide html attributes as the last element of the array.
|
||||
#
|
||||
# Examples:
|
||||
# options_for_select([ "Denmark", ["USA", {:class=>'bold'}], "Sweden" ], ["USA", "Sweden"])
|
||||
# <option value="Denmark">Denmark</option>\n<option value="USA" class="bold" selected="selected">USA</option>\n<option value="Sweden" selected="selected">Sweden</option>
|
||||
#
|
||||
# options_for_select([["Dollar", "$", {:class=>"bold"}], ["Kroner", "DKK", {:onclick => "alert('HI');"}]])
|
||||
# <option value="$" class="bold">Dollar</option>\n<option value="DKK" onclick="alert('HI');">Kroner</option>
|
||||
#
|
||||
# If you wish to specify disabled option tags, set +selected+ to be a hash, with <tt>:disabled</tt> being either a value
|
||||
# or array of values to be disabled. In this case, you can use <tt>:selected</tt> to specify selected option tags.
|
||||
#
|
||||
|
@ -291,10 +300,11 @@ module ActionView
|
|||
selected, disabled = extract_selected_and_disabled(selected)
|
||||
|
||||
options_for_select = container.inject([]) do |options, element|
|
||||
html_attributes = option_html_attributes(element)
|
||||
text, value = option_text_and_value(element)
|
||||
selected_attribute = ' selected="selected"' if option_value_selected?(value, selected)
|
||||
disabled_attribute = ' disabled="disabled"' if disabled && option_value_selected?(value, disabled)
|
||||
options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}>#{html_escape(text.to_s)}</option>)
|
||||
options << %(<option value="#{html_escape(value.to_s)}"#{selected_attribute}#{disabled_attribute}#{html_attributes}>#{html_escape(text.to_s)}</option>)
|
||||
end
|
||||
|
||||
options_for_select.join("\n").html_safe
|
||||
|
@ -486,9 +496,22 @@ module ActionView
|
|||
end
|
||||
|
||||
private
|
||||
def option_html_attributes(element)
|
||||
return "" unless Array === element
|
||||
html_attributes = []
|
||||
element.select { |e| Hash === e }.reduce({}, :merge).each do |k, v|
|
||||
html_attributes << " #{k}=\"#{html_escape(v.to_s)}\""
|
||||
end
|
||||
html_attributes.join
|
||||
end
|
||||
|
||||
def option_text_and_value(option)
|
||||
# Options are [text, value] pairs or strings used for both.
|
||||
if !option.is_a?(String) and option.respond_to?(:first) and option.respond_to?(:last)
|
||||
case
|
||||
when Array === option
|
||||
option = option.reject { |e| Hash === e }
|
||||
[option.first, option.last]
|
||||
when !option.is_a?(String) && option.respond_to?(:first) && option.respond_to?(:last)
|
||||
[option.first, option.last]
|
||||
else
|
||||
[option, option]
|
||||
|
|
|
@ -767,6 +767,62 @@ class FormOptionsHelperTest < ActionView::TestCase
|
|||
html
|
||||
end
|
||||
|
||||
def test_options_for_select_with_element_attributes
|
||||
assert_dom_equal(
|
||||
"<option value=\"<Denmark>\" class=\"bold\"><Denmark></option>\n<option value=\"USA\" onclick=\"alert('Hello World');\">USA</option>\n<option value=\"Sweden\">Sweden</option>\n<option value=\"Germany\">Germany</option>",
|
||||
options_for_select([ [ "<Denmark>", { :class => 'bold' } ], [ "USA", { :onclick => "alert('Hello World');" } ], [ "Sweden" ], "Germany" ])
|
||||
)
|
||||
end
|
||||
|
||||
def test_options_for_select_with_element_attributes_and_selection
|
||||
assert_dom_equal(
|
||||
"<option value=\"<Denmark>\"><Denmark></option>\n<option value=\"USA\" class=\"bold\" selected=\"selected\">USA</option>\n<option value=\"Sweden\">Sweden</option>",
|
||||
options_for_select([ "<Denmark>", [ "USA", { :class => 'bold' } ], "Sweden" ], "USA")
|
||||
)
|
||||
end
|
||||
|
||||
def test_options_for_select_with_element_attributes_and_selection_array
|
||||
assert_dom_equal(
|
||||
"<option value=\"<Denmark>\"><Denmark></option>\n<option value=\"USA\" class=\"bold\" selected=\"selected\">USA</option>\n<option value=\"Sweden\" selected=\"selected\">Sweden</option>",
|
||||
options_for_select([ "<Denmark>", [ "USA", { :class => 'bold' } ], "Sweden" ], [ "USA", "Sweden" ])
|
||||
)
|
||||
end
|
||||
|
||||
def test_option_html_attributes_from_without_hash
|
||||
assert_dom_equal(
|
||||
"",
|
||||
option_html_attributes([ 'foo', 'bar' ])
|
||||
)
|
||||
end
|
||||
|
||||
def test_option_html_attributes_with_single_element_hash
|
||||
assert_dom_equal(
|
||||
" class=\"fancy\"",
|
||||
option_html_attributes([ 'foo', 'bar', { :class => 'fancy' } ])
|
||||
)
|
||||
end
|
||||
|
||||
def test_option_html_attributes_with_multiple_element_hash
|
||||
assert_dom_equal(
|
||||
" class=\"fancy\" onclick=\"alert('Hello World');\"",
|
||||
option_html_attributes([ 'foo', 'bar', { :class => 'fancy', 'onclick' => "alert('Hello World');" } ])
|
||||
)
|
||||
end
|
||||
|
||||
def test_option_html_attributes_with_multiple_hashes
|
||||
assert_dom_equal(
|
||||
" class=\"fancy\" onclick=\"alert('Hello World');\"",
|
||||
option_html_attributes([ 'foo', 'bar', { :class => 'fancy' }, { 'onclick' => "alert('Hello World');" } ])
|
||||
)
|
||||
end
|
||||
|
||||
def test_option_html_attributes_with_special_characters
|
||||
assert_dom_equal(
|
||||
" onclick=\"alert("<code>")\"",
|
||||
option_html_attributes([ 'foo', 'bar', { :onclick => %(alert("<code>")) } ])
|
||||
)
|
||||
end
|
||||
|
||||
def test_grouped_collection_select
|
||||
@continents = [
|
||||
Continent.new("<Africa>", [Country.new("<sa>", "<South Africa>"), Country.new("so", "Somalia")] ),
|
||||
|
|
Loading…
Reference in a new issue