2012-01-26 20:10:34 +00:00
|
|
|
module SimpleForm
|
|
|
|
module Inputs
|
|
|
|
class CollectionInput < Base
|
|
|
|
# Default boolean collection for use with selects/radios when no
|
|
|
|
# collection is given. Always fallback to this boolean collection.
|
|
|
|
# Texts can be translated using i18n in "simple_form.yes" and
|
|
|
|
# "simple_form.no" keys. See the example locale file.
|
|
|
|
def self.boolean_collection
|
|
|
|
i18n_cache :boolean_collection do
|
2013-01-28 21:02:59 +00:00
|
|
|
[ [I18n.t(:"simple_form.yes", default: 'Yes'), true],
|
|
|
|
[I18n.t(:"simple_form.no", default: 'No'), false] ]
|
2012-01-26 20:10:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-03-11 22:41:25 +00:00
|
|
|
def input(wrapper_options = nil)
|
2012-01-26 20:10:34 +00:00
|
|
|
raise NotImplementedError,
|
|
|
|
"input should be implemented by classes inheriting from CollectionInput"
|
|
|
|
end
|
|
|
|
|
|
|
|
def input_options
|
|
|
|
options = super
|
2013-02-06 10:42:20 +00:00
|
|
|
|
2012-01-26 20:10:34 +00:00
|
|
|
options[:include_blank] = true unless skip_include_blank?
|
2014-07-09 21:50:08 +00:00
|
|
|
translate_option options, :prompt
|
|
|
|
translate_option options, :include_blank
|
2013-02-06 10:42:20 +00:00
|
|
|
|
2012-01-26 20:10:34 +00:00
|
|
|
options
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def collection
|
|
|
|
@collection ||= begin
|
|
|
|
collection = options.delete(:collection) || self.class.boolean_collection
|
|
|
|
collection.respond_to?(:call) ? collection.call : collection.to_a
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def has_required?
|
2013-11-03 11:19:52 +00:00
|
|
|
super && (input_options[:include_blank] || input_options[:prompt] || multiple?)
|
2012-01-26 20:10:34 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Check if :include_blank must be included by default.
|
|
|
|
def skip_include_blank?
|
|
|
|
(options.keys & [:prompt, :include_blank, :default, :selected]).any? || multiple?
|
|
|
|
end
|
|
|
|
|
|
|
|
def multiple?
|
|
|
|
!!options[:input_html].try(:[], :multiple)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Detect the right method to find the label and value for a collection.
|
|
|
|
# If no label or value method are defined, will attempt to find them based
|
|
|
|
# on default label and value methods that can be configured through
|
|
|
|
# SimpleForm.collection_label_methods and
|
|
|
|
# SimpleForm.collection_value_methods.
|
|
|
|
def detect_collection_methods
|
|
|
|
label, value = options.delete(:label_method), options.delete(:value_method)
|
|
|
|
|
|
|
|
unless label && value
|
|
|
|
common_method_for = detect_common_display_methods
|
|
|
|
label ||= common_method_for[:label]
|
|
|
|
value ||= common_method_for[:value]
|
|
|
|
end
|
|
|
|
|
|
|
|
[label, value]
|
|
|
|
end
|
|
|
|
|
|
|
|
def detect_common_display_methods(collection_classes = detect_collection_classes)
|
|
|
|
collection_translated = translate_collection if collection_classes == [Symbol]
|
|
|
|
|
|
|
|
if collection_translated || collection_classes.include?(Array)
|
2013-06-18 19:55:27 +00:00
|
|
|
{ label: :first, value: :second }
|
2012-01-26 20:10:34 +00:00
|
|
|
elsif collection_includes_basic_objects?(collection_classes)
|
2013-01-28 21:02:59 +00:00
|
|
|
{ label: :to_s, value: :to_s }
|
2012-01-26 20:10:34 +00:00
|
|
|
else
|
2014-04-02 18:06:36 +00:00
|
|
|
detect_method_from_class(collection_classes)
|
2012-01-26 20:10:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-04-02 18:06:36 +00:00
|
|
|
def detect_method_from_class(collection_classes)
|
|
|
|
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
|
|
|
|
|
2012-01-26 20:10:34 +00:00
|
|
|
def detect_collection_classes(some_collection = collection)
|
|
|
|
some_collection.map { |e| e.class }.uniq
|
|
|
|
end
|
|
|
|
|
|
|
|
def collection_includes_basic_objects?(collection_classes)
|
|
|
|
(collection_classes & [
|
|
|
|
String, Integer, Fixnum, Bignum, Float, NilClass, Symbol, TrueClass, FalseClass
|
|
|
|
]).any?
|
|
|
|
end
|
|
|
|
|
|
|
|
def translate_collection
|
2014-04-04 17:43:22 +00:00
|
|
|
if translated_collection = translate_from_namespace(:options)
|
2012-01-26 20:10:34 +00:00
|
|
|
@collection = collection.map do |key|
|
2014-04-04 17:49:18 +00:00
|
|
|
html_key = "#{key}_html".to_sym
|
|
|
|
|
|
|
|
if translated_collection[html_key]
|
|
|
|
[translated_collection[html_key].html_safe || key, key.to_s]
|
|
|
|
else
|
|
|
|
[translated_collection[key] || key, key.to_s]
|
|
|
|
end
|
2012-01-26 20:10:34 +00:00
|
|
|
end
|
|
|
|
true
|
|
|
|
end
|
|
|
|
end
|
2013-02-06 11:06:38 +00:00
|
|
|
|
|
|
|
def translate_option(options, key)
|
2014-04-03 18:22:09 +00:00
|
|
|
if options[key] == :translate
|
|
|
|
namespace = key.to_s.pluralize
|
2013-02-06 11:06:38 +00:00
|
|
|
|
2014-04-04 17:43:22 +00:00
|
|
|
options[key] = translate_from_namespace(namespace, true)
|
2013-02-06 11:06:38 +00:00
|
|
|
end
|
|
|
|
end
|
2012-01-26 20:10:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|