Skip to content

Instantly share code, notes, and snippets.

@OneDivZero
Last active October 2, 2020 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OneDivZero/17f9b82cdca262a6ab6c36734b53382f to your computer and use it in GitHub Desktop.
Save OneDivZero/17f9b82cdca262a6ab6c36734b53382f to your computer and use it in GitHub Desktop.
# rubocop:disable Rails/OutputSafety
class UspListInput < SimpleForm::Inputs::StringInput
# INFO: wrapper_options := {:class=>"form-control", :error_class=>"is-invalid", :valid_class=>"is-valid"}
def input(_wrapper_options)
input_html_options[:type] ||= input_type
template.content_tag(:div, id: input_id, class: custom_wrapper_style, data: { prefix: input_id }) do
template.concat(build_markup)
end
end
def input_type
:string
end
private def blank_entry
{ text: nil, note: nil }
end
private def usp_list
initialize_list!
entries = object.public_send(attribute_name)
entries.push(blank_entry) if entries.blank?
entries
end
private def initialize_list!
return if object.public_send(attribute_name).is_a?(Array)
object.public_send("#{attribute_name}=".to_sym, [])
end
private def build_markup
markup = []
usp_list.map.with_index(1) do |entry, index|
markup << build_entry(entry, index)
end
markup.join.html_safe
end
private def build_entry(entry, index)
template.content_tag(:div, class: 'row usp-entry') do
result = []
result << build_entry_label(entry, index)
result << build_entry_text_field(entry, index)
result << build_entry_note_field(entry, index)
result.join.html_safe
end
end
private def build_entry_label(entry, index)
template.content_tag(:div, class: 'col-12 label') do
@builder.label(entry_label_for(entry, index))
end
end
private def build_entry_text_field(entry, index)
template.content_tag(:div, class: 'col-12 text') do
build_field_for(entry, :text, index)
end
end
private def build_entry_note_field(entry, index)
template.content_tag(:div, class: 'col-12 note') do
build_field_for(entry, :note, index)
end
end
private def build_field_for(entry, name, index)
options = input_html_options_for(entry, name, index)
@builder.text_field(nil, options)
end
private def input_html_options_for(entry, name, index)
input_html_options.merge(
value: entry[name],
name: field_name_for(name),
id: field_id_for(name, index),
placeholder: placeholder_for(name),
class: 'form-control'
)
end
# NOTE: For an array of hashes the field-name must be build this way:
# "#{object_name}[#{attribute_name}][][#{name}]"
# If you have only a simple array of strings, build it this way:
# "#{object_name}[#{attribute_name}][#{name}][]"
private def field_name_for(name)
"#{object_name}[#{attribute_name}][][#{name}]"
end
private def field_id_for(name, index)
"#{object_name}_#{attribute_name}_#{name}_#{index}"
end
private def placeholder_for(name)
return 'USP' if name.eql?(:text)
return 'Hinweis' if name.eql?(:note)
nil
end
private def entry_label_for(entry, index)
return 'Neuer Eintrag' if entry[:text].blank? && entry[:note].blank?
"Eintrag #{index}"
end
private def input_id
"#{object_name}_#{attribute_name}"
end
private def custom_wrapper_style
self.class.name.tableize.parameterize.dasherize
end
end
# rubocop:enable Rails/OutputSafety
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment