Class: Kithe::RepeatableInputGenerator

Inherits:
Object
  • Object
show all
Defined in:
app/simple_form_enhancements/kithe/repeatable_input_generator.rb

Overview

Uses our multi_input simple_form wrapper.

This is normally expected only to be called by Kithe::FormBuilder#repeatable_attr_input , see docs there, as well as guide docs at [Kithe Forms Guide](../../../guides/forms.md)

FUTURE: more args to customize classses and labels.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(form_builder, attribute_name, caller_content_block, primitive: nil, html_attributes: nil, build: nil, simple_form_input_args: {}) ⇒ RepeatableInputGenerator

Returns a new instance of RepeatableInputGenerator.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 13

def initialize(form_builder, attribute_name, caller_content_block, primitive: nil, html_attributes: nil, build: nil, simple_form_input_args: {})
  @form_builder = form_builder
  @attribute_name = attribute_name
  @caller_content_block = caller_content_block
  @primitive = primitive
  @html_attributes = html_attributes
  @simple_form_input_args = simple_form_input_args

  unless attr_json_registration && attr_json_registration.type.is_a?(AttrJson::Type::Array)
    raise ArgumentError, "can only be used with attr_json-registered attributes"
  end

  unless base_model.class.method_defined?("#{attribute_name}_attributes=".to_sym)
    raise ArgumentError, "Needs a '#{attribute_name}_attributes=' method, usually from attr_json_accepts_nested_attributes_for"
  end

  if html_attributes.present? && (!primitive? || caller_content_block)
    raise ArgumentError, "html_attributes argument is only valid if primitive field without block given"
  end

  # kinda cheesy, but seems good enough?
  if build == :at_least_one && base_model.send(attribute_name).blank?
    if primitive?
      base_model.send("#{attribute_name}=", [""])
    else
      base_model.send("#{attribute_name}=", [{}])
    end
  end
end

Instance Attribute Details

#attribute_nameObject (readonly)

Returns the value of attribute attribute_name.



8
9
10
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 8

def attribute_name
  @attribute_name
end

#caller_content_blockObject (readonly)

the block that captures what the caller wants to be repeatable content. It should take one block arg, a form_builder.



11
12
13
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 11

def caller_content_block
  @caller_content_block
end

#form_builderObject (readonly)

Returns the value of attribute form_builder.



8
9
10
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 8

def form_builder
  @form_builder
end

#html_attributesObject (readonly)

Returns the value of attribute html_attributes.



8
9
10
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 8

def html_attributes
  @html_attributes
end

#simple_form_input_argsObject (readonly)

Returns the value of attribute simple_form_input_args.



8
9
10
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 8

def simple_form_input_args
  @simple_form_input_args
end

Instance Method Details

#primitive?Boolean

If they passed no content block, assume primitive mode

Returns:

  • (Boolean)


63
64
65
66
67
68
69
70
71
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 63

def primitive?
  if @primitive.nil?
    # Guess, if they passed in no block, they gotta get primitive, or else
    # if the attr_json registration looks primitive.
    @caller_content_block.nil? || attr_json_registration.type.base_type_primitive?
  else
    @primitive
  end
end

#renderObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 43

def render
  # Rails form_builder doesn't create the right input names on nil,
  # we need an empty array so it knows it's a to-many.
  if base_model.send(attribute_name).nil?
    base_model.send("#{attribute_name}=", [])
  end

  # simple_form #input method, with a block for custom input content.
  form_builder.input(attribute_name, wrapper: :vertical_collection, **simple_form_input_args) do
    template.safe_join([
      placeholder_hidden_input,
      existing_value_inputs,
      template.(:div, class: "repeatable-add-link") do
        add_another_link
      end
    ])
  end
end