Merge pull request #690 from svendahlstrand/grouped_collection_procs
Allow procs for label and value methods in grouped collection selects.
This commit is contained in:
commit
16f31452b7
|
@ -277,34 +277,48 @@ end
|
||||||
module ActionView::Helpers
|
module ActionView::Helpers
|
||||||
class FormBuilder
|
class FormBuilder
|
||||||
include SimpleForm::ActionViewExtensions::Builder
|
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
|
# 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
|
# 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.
|
# callable object, then it just delegates back to original collection select.
|
||||||
#
|
# FIXME: remove when support only Rails 4.0 forward
|
||||||
alias :original_collection_select :collection_select
|
# https://github.com/rails/rails/commit/9035324367526af0300477a58b6d3efc15d1a5a8
|
||||||
def collection_select(attribute, collection, value_method, text_method, options={}, html_options={})
|
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)
|
if value_method.respond_to?(:call) || text_method.respond_to?(:call)
|
||||||
collection = collection.map do |item|
|
collection = collection.map do |item|
|
||||||
value = value_for_collection(item, value_method)
|
value = value_for_collection(item, value_method)
|
||||||
text = value_for_collection(item, text_method)
|
text = value_for_collection(item, text_method)
|
||||||
|
|
||||||
default_html_options = default_html_options_for_collection(item, value, options, html_options)
|
[value, text]
|
||||||
disabled = value if default_html_options[:disabled]
|
|
||||||
selected = value if default_html_options[:selected]
|
|
||||||
|
|
||||||
[value, text, selected, disabled]
|
|
||||||
end
|
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
|
value_method, text_method = :first, :last
|
||||||
|
selected = extract_selected_and_disabled_and_call_procs selected, collection
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,21 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
||||||
end
|
end
|
||||||
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
|
test 'grouped collection with associations' do
|
||||||
tag_groups = [
|
tag_groups = [
|
||||||
TagGroup.new(1, "Group of Tags", [Tag.new(1, "Tag 1"), Tag.new(2, "Tag 2")]),
|
TagGroup.new(1, "Group of Tags", [Tag.new(1, "Tag 1"), Tag.new(2, "Tag 2")]),
|
||||||
|
|
Loading…
Reference in New Issue