class MultiValueInput < SimpleForm::Inputs::CollectionInput
def input(wrapper_options)
@rendered_first_element = false
input_html_classes.unshift('string')
input_html_options[:name] ||= "#{object_name}[#{attribute_name}][]"
outer_wrapper do
buffer_each(collection) do |value, index|
inner_wrapper do
build_field(value, index)
end
end
end
end
protected
def buffer_each(collection)
collection.each_with_object('').with_index do |(value, buffer), index|
buffer << yield(value, index)
end
end
def outer_wrapper
"
\n"
end
def inner_wrapper
<<-HTML
#{yield}
HTML
end
private
# Although the 'index' parameter is not used in this implementation it is useful in an
# an overridden version of this method, especially when the field is a complex object and
# the override defines nested fields.
def build_field_options(value, index)
options = input_html_options.dup
options[:value] = value
if @rendered_first_element
options[:id] = nil
options[:required] = nil
else
options[:id] ||= input_dom_id
end
options[:class] ||= []
options[:class] += ["#{input_dom_id} form-control multi-text-field"]
options[:'aria-labelledby'] = label_id
@rendered_first_element = true
options
end
def build_field(value, index)
options = build_field_options(value, index)
if options.delete(:type) == 'textarea'.freeze
@builder.text_area(attribute_name, options)
else
@builder.text_field(attribute_name, options)
end
end
def label_id
input_dom_id + '_label'
end
def input_dom_id
input_html_options[:id] || "#{object_name}_#{attribute_name}"
end
def collection
@collection ||= begin
val = object[attribute_name]
col = val.respond_to?(:to_ary) ? val.to_ary : val
col.reject { |value| value.to_s.strip.blank? } + ['']
end
end
def multiple?; true; end
end