Class: Fluxbit::FormBuilder

Inherits:
ActionView::Helpers::FormBuilder
  • Object
show all
Includes:
ActionView::Helpers::OutputSafetyHelper
Defined in:
app/helpers/fluxbit/form_builder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#templateObject (readonly)

Returns the value of attribute template.



5
6
7
# File 'app/helpers/fluxbit/form_builder.rb', line 5

def template
  @template
end

Instance Method Details

#error_for(method) ⇒ Object



39
40
41
42
43
44
# File 'app/helpers/fluxbit/form_builder.rb', line 39

def error_for(method)
  return if object.blank?
  return unless object.errors.key?(method)

  raw object.errors.full_messages_for(method)&.first
end

#errors_summary(within: :container) ⇒ Object



9
10
11
12
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
# File 'app/helpers/fluxbit/form_builder.rb', line 9

def errors_summary(within: :container)
  return if object.blank?
  return unless object.errors.any?

  title = I18n.t(
    "polaris.form_builder.errors_summary",
    count: object.errors.count,
    model: object.class.model_name.human.downcase
  )

  render Fluxbit::BannerComponent.new(
    title: title,
    status: :critical,
    within: within,
    data: { errors_summary: true }
  ) do |banner|
    parts = []

    parts << render(Fluxbit::ListComponent.new) do |list|
      object.errors.full_messages.each do |error|
        list.with_item { template.sanitize(error.to_s, tags: [], attributes: []) }
      end
    end

    parts << template.capture { yield(banner) } if block_given?

    template.safe_join(parts)
  end
end

#fluxbit_inline_error_for(method, **options, &block) ⇒ Object



46
47
48
49
50
51
52
53
# File 'app/helpers/fluxbit/form_builder.rb', line 46

def fluxbit_inline_error_for(method, **options, &block)
  error_message = error_for(method)
  return unless error_message

  render(Fluxbit::InlineErrorComponent.new(**options, &block)) do
    error_message
  end
end

#fx_radio_group_button(method, **options, &block) ⇒ Object



80
81
82
83
# File 'app/helpers/fluxbit/form_builder.rb', line 80

def fx_radio_group_button(method, **options, &block)
  options[:name] ||= "#{@object_name}[#{method}]"
  render Fluxbit::Form::RadioGroupButtonComponent.new(**options), &block
end

#fx_select(method, choices = nil, options = {}, html_options = {}, &block) ⇒ Object

Mimics Rails’ form.select signature: select(method, choices = nil, options = {}, html_options = {}, &block)

Examples:

Basic usage

form.fx_select :role, ["Admin", "User", "Guest"]

With options

form.fx_select :country, countries, { prompt: "Select a country" }, { class: "custom-class" }

With pre-formatted options

form.fx_select :status, options_for_select(statuses, selected: "active")

Parameters:

  • method (Symbol)

    The attribute name

  • choices (Array, Hash, String, nil) (defaults to: nil)

    Options for the select (raw data or pre-formatted HTML)

  • options (Hash) (defaults to: {})

    Options like prompt, include_blank, selected, disabled

  • html_options (Hash) (defaults to: {})

    HTML attributes for the select tag

  • block (Proc)

    Optional block for custom options



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'app/helpers/fluxbit/form_builder.rb', line 102

def fx_select(method, choices = nil, options = {}, html_options = {}, &block)
  # Handle Rails-style signature
  all_options = html_options.merge(options)

  # Set the choices/options
  all_options[:options] = choices if choices.present?

  # Add error handling
  all_options[:error] ||= error_for(method)
  all_options[:error] = !!all_options[:error] if all_options[:error_hidden] && all_options[:error]

  # Set selected value from object if not explicitly provided
  value = object&.public_send(method)
  all_options[:selected] ||= value if value.present?

  render Fluxbit::Form::SelectComponent.new(form: self, attribute: method, **all_options, &block)
end

#fx_submit(content = nil, **options, &block) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'app/helpers/fluxbit/form_builder.rb', line 120

def fx_submit(content = nil, **options, &block)
  options[:form] = self
  options[:content] = content if content.present?
  options[:color] ||= :primary
  options[:size] ||= 2
  options[:disabled] = true if object&.persisted? && !object.valid?

  if block_given?
    render Fluxbit::ButtonComponent.new(**options) do |*args|
      yield(*args)
    end
  else
    render Fluxbit::ButtonComponent.new(**options)
  end
end