module Abyme::ViewHelpers

Public Instance Methods

abyme_for(association, form, options = {}) { |abyme_builder( association: association, form: form, context: self, partial: options )| ... } click to toggle source

<div data-controller=“abyme” data-limit=“3” id=“abyme–tasks”>

...

</div>

# File lib/abyme/view_helpers.rb, line 40
def abyme_for(association, form, options = {}, &block)
  content_tag(:div, data: {controller: "abyme", limit: options[:limit], min_count: options[:min_count]}, id: "abyme--#{association}") do
    if block
      yield(
        Abyme::AbymeBuilder.new(
          association: association, form: form, context: self, partial: options[:partial]
        )
      )
    else
      # model = association.to_s.singularize.classify.constantize
      model = association.to_s.singularize
      concat(persisted_records_for(association, form, options))
      concat(new_records_for(association, form, options))
      concat(add_associated_record(content: options[:button_text] || "Add #{model}"))
    end
  end
end
Also aliased as: abymize
abymize(association, form, options = {}, &block)
Alias for: abyme_for
add_associated_record(options = {}, &block) click to toggle source

these helpers will call the create_button method to generate the buttons for add and remove associations with the right action and a default content text for each button

# File lib/abyme/view_helpers.rb, line 199
def add_associated_record(options = {}, &block)
  action = "click->abyme#add_association"
  options[:content] ||= "Add Association"
  create_button(action, options, &block)
end
Also aliased as: add_association
add_association(options = {}, &block)
new_records_for(association, form, options = {}) { |f| ... } click to toggle source
  • wrapper_html (Hash)

allows you to pass any html attributes to the the html element wrapping all the fields

# File lib/abyme/view_helpers.rb, line 101
def new_records_for(association, form, options = {}, &block)
  options[:wrapper_html] ||= {}

  wrapper_default = {
    data: {
      abyme_target: "associations",
      association: association,
      abyme_position: options[:position] || :end
    }
  }

  fields_default = {data: {target: "abyme.fields abyme.newFields"}}

  content_tag(:div, build_attributes(wrapper_default, options[:wrapper_html])) do
    content_tag(:template, class: "abyme--#{association.to_s.singularize}_template", data: {abyme_target: "template"}) do
      fields_for_builder form, association, association.to_s.classify.constantize.new, child_index: "NEW_RECORD" do |f|
        content_tag(:div, build_attributes(fields_default, basic_fields_markup(options[:fields_html], association))) do
          # Here, if a block is passed, we're passing the association fields to it, rather than the form itself
          # block_given? ? yield(f) : render(options[:partial] || "abyme/#{association.to_s.singularize}_fields", f: f)
          block ? yield(f) : render_association_partial(association, f, options[:partial])
        end
      end
    end
  end
end
persisted_records_for(association, form, options = {}) { |f| ... } click to toggle source
  • wrapper_html (Hash)

allows you to pass any html attributes to the the html element wrapping all the fields

# File lib/abyme/view_helpers.rb, line 168
def persisted_records_for(association, form, options = {})
  records = options[:collection] || form.object.send(association)
  # return if records.empty?

  options[:wrapper_html] ||= {}
  fields_default = {data: {abyme_target: "fields"}}

  if options[:order].present?
    records = records.order(options[:order])
    # by calling the order method on the AR collection
    # we get rid of the records with errors
    # so we have to get them back with the 2 lines below
    invalids = form.object.send(association).reject(&:persisted?)
    records = records.to_a.concat(invalids) if invalids.any?
  end

  content_tag(:div, options[:wrapper_html]) do
    fields_for_builder(form, association, records) do |f|
      content_tag(:div, build_attributes(fields_default, basic_fields_markup(options[:fields_html], association))) do
        block_given? ? yield(f) : render_association_partial(association, f, options[:partial])
      end
    end
  end
end
remove_associated_record(options = {}, &block) click to toggle source
# File lib/abyme/view_helpers.rb, line 205
def remove_associated_record(options = {}, &block)
  action = "click->abyme#remove_association"
  options[:content] ||= "Remove Association"
  create_button(action, options, &block)
end
Also aliased as: remove_association
remove_association(options = {}, &block)

Private Instance Methods

basic_fields_markup(html, association = nil) click to toggle source

generates the default html classes for fields add optional classes if present

# File lib/abyme/view_helpers.rb, line 263
def basic_fields_markup(html, association = nil)
  if html && html[:class]
    html[:class] = "abyme--fields #{association.to_s.singularize}-fields #{html[:class]}"
  else
    html ||= {}
    html[:class] = "abyme--fields #{association.to_s.singularize}-fields"
  end
  html
end
build_attributes(default, attr) click to toggle source

add optionals html attributes without overwritting the default or already present ones

# File lib/abyme/view_helpers.rb, line 278
def build_attributes(default, attr)
  # Add new data attributes values to the default ones (only values)
  if attr[:data]
    default[:data].each do |key, value|
      default[:data][key] = "#{value} #{attr[:data][key]}".strip
    end
    # Add new data attributes (keys & values)
    default[:data] = default[:data].merge(attr[:data].reject { |key, _| default[:data][key] })
  end
  # Merge data attributes to the hash of html attributes
  default.merge(attr.reject { |key, _| key == :data })
end
create_button(action, options, &block) click to toggle source
  • html (Hash)

to pass any html attributes you want.

# File lib/abyme/view_helpers.rb, line 245
def create_button(action, options, &block)
  options[:html] ||= {}
  options[:tag] ||= :button

  if block
    content_tag(options[:tag], {data: {action: action}}.merge(options[:html])) do
      capture(&block)
    end
  else
    content_tag(options[:tag], options[:content], {data: {action: action}}.merge(options[:html]))
  end
end
fields_for_builder(form, association, records, options = {}, &block) click to toggle source

If form builder inherits from SimpleForm, we should use its fields_for helper to keep the wrapper options :nocov:

# File lib/abyme/view_helpers.rb, line 220
def fields_for_builder(form, association, records, options = {}, &block)
  if defined?(SimpleForm) && form.instance_of?(SimpleForm::FormBuilder)
    form.simple_fields_for(association, records, options, &block)
  else
    form.fields_for(association, records, options, &block)
  end
end
render_association_partial(association, form, partial = nil, context = nil) click to toggle source

renders a partial based on the passed path, or will expect a partial to be found in the views/abyme directory.

# File lib/abyme/view_helpers.rb, line 295
def render_association_partial(association, form, partial = nil, context = nil)
  partial_path = partial || "abyme/#{association.to_s.singularize}_fields"
  context ||= self
  context.render(partial: partial_path, locals: {f: form})
end