Class: Fluxbit::Form::FormBuilderComponent

Inherits:
Component
  • Object
show all
Defined in:
app/components/fluxbit/form/form_builder_component.rb

Constant Summary collapse

TEXT_TYPES =
%w[text email password number search time date datetime-local].freeze
INPUT_TYPES =
%w[upload upload_image toggle textarea spacer select select_free range radio checkbox].freeze

Instance Method Summary collapse

Constructor Details

#initialize(form: nil, gap: 4, grid_cols: 2, show_errors: true, elements: [], **props) ⇒ FormBuilderComponent

Returns a new instance of FormBuilderComponent.



28
29
30
31
32
33
34
35
36
37
38
# File 'app/components/fluxbit/form/form_builder_component.rb', line 28

def initialize(form: nil, gap: 4, grid_cols: 2, show_errors: true, elements: [], **props)
  super
  @form = form
  @object = form&.object
  @elements = elements
  @props = props
  @gap = gap
  @grid_cols = grid_cols
  @show_errors = show_errors
  add(class: grid_styles, to: @props) unless grid_styles && grid_styles.empty?
end

Instance Method Details

#callObject



111
112
113
114
# File 'app/components/fluxbit/form/form_builder_component.rb', line 111

def call
  elements_rendered = elements? ? elements : safe_join(@elements.map { |element| choose_element(element.merge({ form: @form }), nil) })
  safe_join [ errors?, (:div, elements_rendered, @props) ]
end

#choose_element(kwargs, block = nil) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'app/components/fluxbit/form/form_builder_component.rb', line 70

def choose_element(kwargs, block = nil)
  colspan_element = kwargs.key?(:colspan) ? kwargs.delete(:colspan) : nil
  outer_div = kwargs.key?(:outer_div) ? kwargs.delete(:outer_div) : ""
  outer_div += colspan(colspan_element)
  return (:div, block.call, class: outer_div) if kwargs[:type] == :html

  kwargs[:show_errors] = false if kwargs[:type] == :group
  component_klass = "Fluxbit::#{if (TEXT_TYPES + INPUT_TYPES + [ 'label', 'group', '' ]).include?(kwargs[:type].to_s)
                                  'Form::'
                                else
                                  ''
                                end}#{element_type(kwargs[:type])}Component".constantize

  unless kwargs[:with_content]
    return (:div, render(component_klass.new(**kwargs), &block), class: outer_div)
  end

  content = kwargs.delete(:with_content)
   :div, render(component_klass.new(**kwargs).with_content(content), &block), class: outer_div
end

#colspan(colspan_element) ⇒ Object



48
49
50
51
52
53
# File 'app/components/fluxbit/form/form_builder_component.rb', line 48

def colspan(colspan_element)
  return "" if colspan_element.nil?
  return "col-span-#{colspan_element}" if colspan_element.class != Hash

  colspan_element.map { |size, col| "#{size == :default ? '' : "#{size}:"}col-span-#{col}" }.join(" ")
end

#element_type(type) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'app/components/fluxbit/form/form_builder_component.rb', line 91

def element_type(type)
  return "TextField" if type.nil? || type.to_s.in?(TEXT_TYPES)
  return type.to_s.concat("_input").camelcase if type.to_s.in?(INPUT_TYPES)

  case type
  when :submit
    "Button"
  when :group
    "FormBuilder"
  else
    type.to_s.camelcase
  end
end

#errors?Boolean

Returns:

  • (Boolean)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'app/components/fluxbit/form/form_builder_component.rb', line 55

def errors?
  return "" if !@show_errors || @object.nil? || @object.errors&.none?

   :div, class: "col-span-4" do
    Fluxbit::AlertComponent.new(type: :danger).with_content(
      I18n.t(
        "form_error",
        scope: [ :activerecord, :messages, @object.class.name.underscore.to_sym ],
        count: @object.errors.count,
        default: "#{pluralize(@object.errors.count, 'error')}."
      )
    ).render_in(view_context)
  end
end

#generate_elementsObject



105
106
107
108
109
# File 'app/components/fluxbit/form/form_builder_component.rb', line 105

def generate_elements
  return elements if elements?

  safe_join(@elements.map { |element| choose_element(element.merge({ form: @form }), nil) })
end

#grid_stylesObject



40
41
42
43
44
45
46
# File 'app/components/fluxbit/form/form_builder_component.rb', line 40

def grid_styles
  return "grid gap-#{@gap} grid-cols-#{@grid_cols}" if @grid_cols.class != Hash

  "grid gap-#{@gap} " + @grid_cols.map do |size, col|
    "#{size == :default ? '' : "#{size}:"}grid-cols-#{col}"
  end.join(" ")
end