Class: BulmaPhlex::Rails::FormBuilder

Inherits:
ActionView::Helpers::FormBuilder
  • Object
show all
Includes:
NestedForms
Defined in:
lib/bulma_phlex/rails/form_builder.rb

Overview

# Form Builder

This form builder wraps inputs with [Bulma Form Fields](bulma.io/documentation/form/general/#form-field).

In addition to standard input options, it supports the following Bulma-specific options:

  • ‘suppress_label`: If true, the label will not be rendered.

  • ‘icon_left`: If set, the specified icon will be rendered on the left side of the input.

  • ‘icon_right`: If set, the specified icon will be rendered on the right side of the input.

  • ‘column`: If true, the input will be wrapped in a Bulma column (only within a `columns` block).

  • ‘grid`: If true, the input will be wrapped in a Bulma grid cell (only within a `grid` block).

## Nested Forms

This form builder also includes support for nested forms. Invoke the ‘nested_form_add_button` method to add a button that allows users to dynamically add new nested form rows. Each nested form row can include a delete button using the `nested_form_delete_button` method.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from NestedForms

#fields_for, #nested_form_add_button, #nested_form_delete_button

Instance Attribute Details

#columns_flagObject (readonly)

Returns the value of attribute columns_flag.



24
25
26
# File 'lib/bulma_phlex/rails/form_builder.rb', line 24

def columns_flag
  @columns_flag
end

#grid_flagObject (readonly)

Returns the value of attribute grid_flag.



24
25
26
# File 'lib/bulma_phlex/rails/form_builder.rb', line 24

def grid_flag
  @grid_flag
end

Instance Method Details

#button(value = nil, options = {}) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/bulma_phlex/rails/form_builder.rb', line 159

def button(value = nil, options = {}, &)
  if value.is_a?(Hash)
    options = value
    value = nil
  end

  button_opts, field_opts, icon_opts = parse_button_options(options)

  FormField.new(**field_opts) do
    super(value, button_opts) do |value_from_delivered|
      FormButtonLabel.new(value_from_delivered, **icon_opts, &).render_in(@template)
    end
  end.render_in(@template)
end

#check_box(method, options = {}, checked_value = "1", unchecked_value = "0", &label_block) ⇒ Object Also known as: checkbox



67
68
69
70
# File 'lib/bulma_phlex/rails/form_builder.rb', line 67

def check_box(method, options = {}, checked_value = "1", unchecked_value = "0", &label_block)
  delivered = ->(opts) { super(method, opts, checked_value, unchecked_value) }
  Checkbox.new(self, method, options, delivered, label_block).render_in(@template)
end

#collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block) ⇒ Object Also known as: collection_checkboxes

The collection_check_boxes method is overridden to wrap the checkboxes in a Bulma form field and apply the ‘checkbox` class to the labels. It does so by passing a block to the original method. If you pass a block this logic will be skipped.

Add option ‘stacked: true` to stack the checkboxes vertically.



99
100
101
102
103
104
105
106
107
108
# File 'lib/bulma_phlex/rails/form_builder.rb', line 99

def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)
  wrap_field(method, html_options, add_class: false) do |m, html_opts|
    wrapper_opts, label_class, html_opts[:class] = parse_collection_options(html_opts, "checkbox", "checkboxes")
    block ||= ->(builder) { builder.label(class: label_class) { builder.check_box + builder.text } }

    @template.("div", wrapper_opts) do
      super(m, collection, value_method, text_method, options, html_opts, &block)
    end
  end
end

#collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block) ⇒ Object

The collection_radio_buttons method is overridden to wrap the radio buttons in a Bulma form field and apply the ‘radio` class to the labels. It does so by passing a block to the original method. If you pass a block this logic will be skipped.

Add option ‘stacked: true` to stack the radio buttons vertically.



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/bulma_phlex/rails/form_builder.rb', line 116

def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {},
                             &block)
  wrap_field(method, html_options, add_class: false) do |m, html_opts|
    wrapper_opts, label_class, html_opts[:class] = parse_collection_options(html_opts, "radio", "radios")
    block ||= ->(builder) { builder.label(class: label_class) { builder.radio_button + builder.text } }

    @template.("div", wrapper_opts) do
      super(m, collection, value_method, text_method, options, html_opts, &block)
    end
  end
end

#collection_select(method, collection, value_method, text_method, options = {}, html_options = {}) ⇒ Object



128
129
130
131
132
# File 'lib/bulma_phlex/rails/form_builder.rb', line 128

def collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
  wrap_select_field(method, html_options) do |m, html_opts|
    super(m, collection, value_method, text_method, options, html_opts)
  end
end

#color_field(method, options = {}) ⇒ Object



28
# File 'lib/bulma_phlex/rails/form_builder.rb', line 28

def color_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#columns(minimum_breakpoint: nil, multiline: false, gap: nil, centered: false, vcentered: false) ⇒ Object

Fields declared in a column block will be wrapped in a Bulma column and carry the ‘column` class by default (fields can use the `column` option to set sizes).

## Arguments

  • ‘minimum_breakpoint`: (Symbol, optional) Sets the minimum breakpoint for the columns; default is `:tablet`.

  • ‘multiline`: (Boolean, optional) If true, allows the columns to wrap onto multiple lines.

  • ‘gap`: (optional) Use an integer (0-8) to set the gap size between columns; use a hash keyed by breakpoints to set responsive gap sizes.

  • ‘centered`: (Boolean, optional) If true, centers the columns.

  • ‘vcentered`: (Boolean, optional) If true, vertically centers the columns.



185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/bulma_phlex/rails/form_builder.rb', line 185

def columns(minimum_breakpoint: nil,
            multiline: false,
            gap: nil,
            centered: false,
            vcentered: false, &)
  @columns_flag = true
  columns = @template.capture(&)
  @columns_flag = false

  BulmaPhlex::Columns.new(minimum_breakpoint:, multiline:, gap:, centered:, vcentered:) do
    @template.concat(columns)
  end.render_in(@template)
end

#date_field(method, options = {}) ⇒ Object



32
# File 'lib/bulma_phlex/rails/form_builder.rb', line 32

def date_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#datetime_field(method, options = {}) ⇒ Object



34
# File 'lib/bulma_phlex/rails/form_builder.rb', line 34

def datetime_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#datetime_local_field(method, options = {}) ⇒ Object



35
# File 'lib/bulma_phlex/rails/form_builder.rb', line 35

def datetime_local_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#email_field(method, options = {}) ⇒ Object



39
# File 'lib/bulma_phlex/rails/form_builder.rb', line 39

def email_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#file_field(method, options = {}) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/bulma_phlex/rails/form_builder.rb', line 43

def file_field(method, options = {})
  opts, comp_opts, field_options = parse_file_field_options(options)

  BulmaPhlex::FormField.new(**field_options) do |f|
    f.label { label(method).html_safe } unless options.delete(:suppress_label)
    f.control do
      BulmaPhlex::FileUpload.new(**comp_opts) do |data_attributes|
        opts[:data] = (opts[:data] || {}).merge(data_attributes) if data_attributes
        super(method, opts)
      end.render_in(@template)
    end
  end.render_in(@template)
end

#grid(fixed_columns: nil, auto_count: false, minimum_column_width: nil, gap: nil, column_gap: nil, row_gap: nil) ⇒ Object

Fields declared in a grid block will be wrapped in a Bulma fixed grid and carry the ‘grid` class by default (fields can use the `grid` option to set sizes).

## Arguments

  • ‘fixed_columns`: (Integer, optional) Specifies a fixed number of columns for the grid.

  • ‘auto_count`: (Boolean, optional) If true, the grid will automatically adjust the number

    of columns based on the content.
    
  • ‘minimum_column_width`: (Integer 1-32, optional) Sets a minimum width for the columns in the grid.

  • ‘gap`: (optional) Sets the gap size between grid items from 1-8 with 0.5 increments.

  • ‘column_gap`: (optional) Sets the column gap size between grid items from 1-8 with 0.5 increments.

  • ‘row_gap`: (optional) Sets the row gap size between grid items from 1-8 with 0.5 increments.



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/bulma_phlex/rails/form_builder.rb', line 211

def grid(fixed_columns: nil, # rubocop:disable Metrics/ParameterLists
         auto_count: false,
         minimum_column_width: nil,
         gap: nil,
         column_gap: nil,
         row_gap: nil,
         &)
  @grid_flag = true
  cells = @template.capture(&)
  @grid_flag = false

  BulmaPhlex::Grid.new(fixed_columns:, auto_count:, minimum_column_width:, gap:, column_gap:, row_gap:) do
    @template.concat(cells)
  end.render_in(@template)
end

#label(method, text = nil, options = {}) ⇒ Object

Override label to add Bulma’s ‘label` class by default. Add `:skip_label_class` option to skip adding the class.



80
81
82
83
84
# File 'lib/bulma_phlex/rails/form_builder.rb', line 80

def label(method, text = nil, options = {}, &)
  skip_label_class = options.delete(:skip_label_class)
  options[:class] = Array.wrap(options[:class]) << :label unless skip_label_class
  super
end

#month_field(method, options = {}) ⇒ Object



36
# File 'lib/bulma_phlex/rails/form_builder.rb', line 36

def month_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#number_field(method, options = {}) ⇒ Object



40
# File 'lib/bulma_phlex/rails/form_builder.rb', line 40

def number_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#password_field(method, options = {}) ⇒ Object



27
# File 'lib/bulma_phlex/rails/form_builder.rb', line 27

def password_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#phone_field(method, options = {}) ⇒ Object



31
# File 'lib/bulma_phlex/rails/form_builder.rb', line 31

def phone_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#radio_button(method, tag_value, options = {}) ⇒ Object



73
74
75
76
# File 'lib/bulma_phlex/rails/form_builder.rb', line 73

def radio_button(method, tag_value, options = {})
  delivered = ->(opts) { super(method, tag_value, opts) }
  RadioButton.new(self, method, tag_value, options, delivered).render_in(@template)
end

#range_field(method, options = {}) ⇒ Object



41
# File 'lib/bulma_phlex/rails/form_builder.rb', line 41

def range_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#search_field(method, options = {}) ⇒ Object



29
# File 'lib/bulma_phlex/rails/form_builder.rb', line 29

def search_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#select(method, choices = nil, options = {}, html_options = {}) ⇒ Object



86
87
88
89
90
# File 'lib/bulma_phlex/rails/form_builder.rb', line 86

def select(method, choices = nil, options = {}, html_options = {}, &)
  wrap_select_field(method, html_options) do |m, html_opts|
    super(m, choices, options, html_opts, &)
  end
end

#submit(value = nil, options = {}) ⇒ Object

The following Bulma button options can be passed as options to customize the button:

  • color (String): colors such as “primary” or “danger”

  • size (String): small, normal, medium, or large

  • mode (String): light or dark

  • responsive (Boolean): makes the size responsive

  • fullwidth (Boolean)

  • outlined (Boolean)

  • inverted (Boolean)

  • rounded (Boolean)



145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/bulma_phlex/rails/form_builder.rb', line 145

def submit(value = nil, options = {})
  if value.is_a?(Hash)
    options = value
    value = nil
  end

  options = options.dup
  options[:class] = Array.wrap(options[:class]) << BulmaPhlex::Button.classes_for(**extract_button_options!(options))

  FormField.new do
    super(value, options)
  end.render_in(@template)
end

#telephone_field(method, options = {}) ⇒ Object



30
# File 'lib/bulma_phlex/rails/form_builder.rb', line 30

def telephone_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#text_area(method, options = {}) ⇒ Object Also known as: textarea

Prior to 8.0, the methods text_area and check_box did not have aliases. Defining with the underscore and aliasing to the non-underscored versions allows support for Rails 7.2.



60
61
62
63
64
# File 'lib/bulma_phlex/rails/form_builder.rb', line 60

def text_area(method, options = {})
  wrap_field(method, options, add_class: "textarea") do |m, opts|
    super(m, opts)
  end
end

#text_field(method, options = {}) ⇒ Object



26
# File 'lib/bulma_phlex/rails/form_builder.rb', line 26

def text_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#time_field(method, options = {}) ⇒ Object



33
# File 'lib/bulma_phlex/rails/form_builder.rb', line 33

def time_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#url_field(method, options = {}) ⇒ Object



38
# File 'lib/bulma_phlex/rails/form_builder.rb', line 38

def url_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }

#week_field(method, options = {}) ⇒ Object



37
# File 'lib/bulma_phlex/rails/form_builder.rb', line 37

def week_field(method, options = {}) = wrap_field(method, options) { |m, opts| super(m, opts) }