Allow procs for label and value methods in grouped collection selects.
This commit is contained in:
parent
9a66675b0b
commit
2747d9f2a1
|
@ -277,34 +277,48 @@ end
|
|||
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_collection_select(attribute, collection, value_method, text_method, options, html_options)
|
||||
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
|
||||
|
||||
def value_for_collection(item, value) #:nodoc:
|
||||
value.respond_to?(:call) ? value.call(item) : item.send(value)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -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")]),
|
||||
|
|
Loading…
Reference in New Issue