Add ability to have mixed types in collections.

For example ["Some String", 2, 2.5, :lucky_stiff, nil] will render correct
option tags as you would expect.
This commit is contained in:
jfelchner 2010-12-04 00:36:44 +08:00 committed by Carlos Antonio da Silva
parent 9577ca6a19
commit dbda259a02
2 changed files with 45 additions and 10 deletions

View File

@ -39,19 +39,34 @@ module SimpleForm
# SimpleForm.collection_label_methods and
# SimpleForm.collection_value_methods.
def detect_collection_methods(collection, options)
sample = collection.first || collection.last
common_method_for = detect_common_display_methods(collection)
case sample
when Array
label, value = :first, :last
when Integer
label, value = :to_s, :to_i
when String, Symbol, NilClass
label, value = :to_s, :to_s
options[:label_method] ||= common_method_for[:label]
options[:value_method] ||= common_method_for[:value]
end
def detect_common_display_methods(collection)
collection_classes = detect_collection_classes(collection)
if collection_classes.include? Array
{ :label => :first, :value => :last }
elsif collection_includes_basic_objects(collection_classes)
{ :label => :to_s, :value => :to_s }
else
sample = collection.first || collection.last
{ :label => SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) },
:value => SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) } }
end
end
options[:label_method] ||= label || SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) }
options[:value_method] ||= value || SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) }
def detect_collection_classes(collection)
collection_classes = collection.map { |e| e.class }
collection_classes.uniq
end
def collection_includes_basic_objects(collection_classes)
!(collection_classes & [String, Integer, Fixnum, Bignum, Float, NilClass, Symbol]).empty?
end
end
end

View File

@ -450,6 +450,26 @@ class InputTest < ActionView::TestCase
assert_select 'select option[selected=selected]', '18'
end
test 'input should set the correct value when using a collection that includes floats' do
with_input_for @user, :age, :select, :collection => [2.0, 2.5, 3.0, 3.5, 4.0, 4.5]
assert_select 'select option[value="2.0"]'
assert_select 'select option[value="2.5"]'
end
test 'input should set the correct values when using a collection that uses mixed values' do
with_input_for @user, :age, :select, :collection => ["Hello Kitty", 2, 4.5, :johnny, nil]
assert_select 'select option[value="Hello Kitty"]'
assert_select 'select option[value="2"]'
assert_select 'select option[value="4.5"]'
assert_select 'select option[value="johnny"]'
assert_select 'select option[value=""]'
end
test 'input should include a blank option even if :include_blank is set to false if the collection includes a nil value' do
with_input_for @user, :age, :select, :collection => [nil], :include_blank => false
assert_select 'select option[value=""]'
end
test 'input should automatically set include blank' do
with_input_for @user, :age, :select, :collection => 18..30
assert_select 'select option[value=]', ''