Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Allow procs for label and value methods in grouped collection selects. #690

Merged
merged 2 commits into from

2 participants

@svendahlstrand

This is one solution to issue #623. I'm not to happy about monkey patching Rails though, are there better solutions?

This patch will not be needed when SimpleForm is used with Rails >= 4.0 thanks to this: rails/rails@9035324.

@rafaelfranca
Collaborator

No. This is the best current solution.

Thank you so much and sorry for the delay.

@rafaelfranca rafaelfranca referenced this pull request from a commit
@rafaelfranca rafaelfranca CHANGELOG for #690
Closes #623
cfa07f8
@rafaelfranca rafaelfranca merged commit 5e7f18d into plataformatec:master

1 check failed

Details default The Travis build failed
@svendahlstrand

Awesome, thanks! :smiley:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
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")]),
Something went wrong with that request. Please try again.