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, build: nil) ⇒ 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
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 13

def initialize(form_builder, attribute_name, caller_content_block, primitive: nil, build: nil)
  @form_builder = form_builder
  @attribute_name = attribute_name
  @caller_content_block = caller_content_block
  @primitive = primitive

  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

  # 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

Instance Method Details

#primitive?Boolean

If they passed no content block, assume primitive mode

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 57

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



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'app/simple_form_enhancements/kithe/repeatable_input_generator.rb', line 37

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) do
    template.safe_join([
      placeholder_hidden_input,
      existing_value_inputs,
      template.(:div, class: "repeatable-add-link") do
        add_another_link
      end
    ])
  end
end