Permalink
Browse files

Merge pull request #690 from svendahlstrand/grouped_collection_procs

Allow procs for label and value methods in grouped collection selects.
  • Loading branch information...
2 parents 5ae7ffb + 5e7f18d commit 16f31452b71b081fa4c3212465aa34ef6f46125c @rafaelfranca rafaelfranca committed Jan 2, 2013
View
42 lib/simple_form/action_view_extensions/builder.rb
@@ -277,34 +277,48 @@ def wrap_rendered_collection(collection, options)
module ActionView::Helpers
class FormBuilder
include SimpleForm::ActionViewExtensions::Builder
+ end
- # Override default Rails collection_select helper to handle lambdas/procs in
+ module FormOptionsHelper
+ # Override Rails options_from_collection_for_select to handle lambdas/procs in
# text and value methods, so it works the same way as collection_radio_buttons
# and collection_check_boxes in SimpleForm. If none of text/value methods is a
# callable object, then it just delegates back to original collection select.
- #
- alias :original_collection_select :collection_select
- def collection_select(attribute, collection, value_method, text_method, options={}, html_options={})
+ # FIXME: remove when support only Rails 4.0 forward
+ # https://github.com/rails/rails/commit/9035324367526af0300477a58b6d3efc15d1a5a8
+ alias :original_options_from_collection_for_select :options_from_collection_for_select
+ def options_from_collection_for_select(collection, value_method, text_method, selected = nil)
if value_method.respond_to?(:call) || text_method.respond_to?(:call)
collection = collection.map do |item|
value = value_for_collection(item, value_method)
text = value_for_collection(item, text_method)
- default_html_options = default_html_options_for_collection(item, value, options, html_options)
- disabled = value if default_html_options[:disabled]
- selected = value if default_html_options[:selected]
-
- [value, text, selected, disabled]
+ [value, text]
end
- [:disabled, :selected].each do |option|
- option_value = collection.map(&:pop).compact
- options[option] = option_value if option_value.present?
- end
value_method, text_method = :first, :last
+ selected = extract_selected_and_disabled_and_call_procs selected, collection
+ end
+
+ original_options_from_collection_for_select collection, value_method, text_method, selected
+ end
+
+ private
+
+ def extract_selected_and_disabled_and_call_procs(selected, collection)
+ selected, disabled = extract_selected_and_disabled selected
+ selected_disabled = { :selected => selected, :disabled => disabled }
+
+ selected_disabled.each do |key, check|
+ if check.is_a? Proc
+ values = collection.map { |option| option.first if check.call(option.first) }
+ selected_disabled[key] = values
+ end
end
+ end
- original_collection_select(attribute, collection, value_method, text_method, options, html_options)
+ def value_for_collection(item, value) #:nodoc:
+ value.respond_to?(:call) ? value.call(item) : item.send(value)
end
end
View
15 test/inputs/grouped_collection_select_input_test.rb
@@ -94,6 +94,21 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
end
end
+ test 'grouped collection should allow overriding label and value methods using a lambda' do
+ with_input_for @user, :tag_ids, :grouped_select,
+ :collection => { 'Authors' => ['Jose', 'Carlos'] },
+ :group_method => :last,
+ :label_method => lambda { |i| i.upcase },
+ :value_method => lambda { |i| i.downcase }
+
+ assert_select 'select.grouped_select#user_tag_ids' do
+ assert_select 'optgroup[label=Authors]' do
+ assert_select 'option[value=jose]', 'JOSE'
+ assert_select 'option[value=carlos]', 'CARLOS'
+ end
+ end
+ end
+
test 'grouped collection with associations' do
tag_groups = [
TagGroup.new(1, "Group of Tags", [Tag.new(1, "Tag 1"), Tag.new(2, "Tag 2")]),

0 comments on commit 16f3145

Please sign in to comment.