Class: Spree::Admin::FormBuilder

Inherits:
ActionView::Helpers::FormBuilder
  • Object
show all
Defined in:
app/models/spree/admin/form_builder.rb

Overview

Custom form builder for Spree admin interface

This form builder provides helper methods for creating form fields with consistent styling and behavior across the Spree admin interface. It includes form groups, error handling, help text, and other features.

Instance Method Summary collapse

Instance Method Details

#error_message_on(method, options = {}) ⇒ String

Display error messages for a specific field

Parameters:

  • method (Symbol)

    the field name

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

    additional options for the error message

Returns:

  • (String)

    HTML string containing the error message



14
15
16
# File 'app/models/spree/admin/form_builder.rb', line 14

def error_message_on(method, options = {})
  @template.error_message_on(@object_name, method, objectify_options(options))
end

#spree_check_box(method, options = {}) ⇒ String

Create a checkbox with Spree custom control styling

Parameters:

  • method (Symbol)

    the field name

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

    field options (see #spree_text_field for available options)

Returns:

  • (String)

    HTML string containing the complete form group with custom checkbox



267
268
269
270
271
272
273
274
275
# File 'app/models/spree/admin/form_builder.rb', line 267

def spree_check_box(method, options = {})
  @template.(:div, class: 'form-group') do
    @template.(:div, class: 'form-checkbox') do
      checkbox = @template.check_box(@object_name, method, objectify_options(options.merge(class: 'custom-control-input')))
      label = options[:label] == false ? ''.html_safe : @template.label(@object_name, method, get_label(method, options), class: 'custom-control-label')
      checkbox + label
    end + @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge!(class: 'form-text mt-2 ml-6 pl-1'))
  end
end

#spree_collection_select(method, collection, value_method, text_method, options = {}, html_options = {}) ⇒ String

Create a collection select field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

  • collection (Array)

    collection of objects for the select options

  • value_method (Symbol)

    method to call on each object for the option value

  • text_method (Symbol)

    method to call on each object for the option text

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

    field options including:

    • :autocomplete [Boolean] whether to enable autocomplete functionality

    • other options from #spree_text_field

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

    HTML options for the select element

Returns:

  • (String)

    HTML string containing the complete form group



247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'app/models/spree/admin/form_builder.rb', line 247

def spree_collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
  if options[:autocomplete]
    html_options[:data] ||= {}
    html_options[:data][:controller] ||= 'autocomplete-select'
  else
    html_options[:class] ||= 'form-select'
  end

  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      @template.collection_select(@object_name, method, collection, value_method, text_method, objectify_options(options), html_options) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_date_field(method, options = {}) ⇒ String

Create a date field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    field options (see #spree_text_field for available options)

Returns:

  • (String)

    HTML string containing the complete form group



152
153
154
155
156
157
158
159
# File 'app/models/spree/admin/form_builder.rb', line 152

def spree_date_field(method, options = {})
  options[:class] ||= 'form-input'
  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      @template.date_field(@object_name, method, objectify_options(options)) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_datetime_field(method, options = {}) ⇒ String

Create a datetime field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    field options (see #spree_text_field for available options)

Returns:

  • (String)

    HTML string containing the complete form group



166
167
168
169
170
171
172
173
# File 'app/models/spree/admin/form_builder.rb', line 166

def spree_datetime_field(method, options = {})
  options[:class] ||= 'form-input'
  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      @template.datetime_field(@object_name, method, objectify_options(options)) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_email_field(method, options = {}) ⇒ String

Create an email field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    field options (see #spree_text_field for available options)

Returns:

  • (String)

    HTML string containing the complete form group



138
139
140
141
142
143
144
145
# File 'app/models/spree/admin/form_builder.rb', line 138

def spree_email_field(method, options = {})
  options[:class] ||= 'form-input'
  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      @template.email_field(@object_name, method, objectify_options(options)) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_file_field(method, options = {}) ⇒ String

Create a direct file upload field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    field options

Options Hash (options):

  • :width (Integer)

    Width of the image preview in pixels

  • :height (Integer)

    Height of the image preview in pixels

  • :crop (Boolean)

    Enable image cropping with recommended size indicator

  • :auto_submit (Boolean)

    Automatically submit form when file is selected

  • :can_delete (Boolean)

    Show delete button for removing uploaded image

  • :css (String)

    Additional CSS classes for the upload placeholder area

  • :allowed_file_types (Array)

    Specify the allowed file types

Returns:

  • (String)

    HTML string containing the complete form group with direct file upload field



310
311
312
313
314
315
316
# File 'app/models/spree/admin/form_builder.rb', line 310

def spree_file_field(method, options = {})
  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      @template.render('active_storage/upload_form', form: self, field_name: method, **options) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_money_field(method, options = {}) ⇒ String

Create a money/currency field with Spree form styling and locale-aware formatting

This field displays amounts in the user’s locale format (e.g., “1.234,56” for German) and normalizes values to standard decimal format before form submission.

Parameters:

  • method (Symbol)

    the field name

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

    field options including:

    • :currency [String] the currency code (e.g., ‘USD’, ‘EUR’, ‘PLN’) - used for symbol display

    • :value [BigDecimal, Float, String] the value to display (will be formatted for locale)

    • other options from #spree_text_field

Returns:

  • (String)

    HTML string containing the complete form group with money field



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'app/models/spree/admin/form_builder.rb', line 82

def spree_money_field(method, options = {})
  currency = options.delete(:currency)
  prepend = options.delete(:prepend)
  append = options.delete(:append)

  # Get currency object for formatting
  currency_obj = currency.present? ? ::Money::Currency.find(currency) : nil

  # Use currency symbol as append if currency is provided and no append specified
  if currency_obj.present? && append.nil?
    append = currency_obj.symbol
  end

  # Get decimal/thousands separators from currency or fall back to I18n locale
  locale = I18n.locale
  if currency_obj.present?
    decimal_separator = currency_obj.decimal_mark
    thousands_separator = currency_obj.thousands_separator
  else
    decimal_separator = I18n.t(:'number.currency.format.separator', default: '.')
    thousands_separator = I18n.t(:'number.currency.format.delimiter', default: ',')
  end

  # Format the value for display if present
  if options[:value].present?
    options[:value] = format_money_value(options[:value], decimal_separator)
  elsif @object.respond_to?(method) && @object.send(method).present?
    options[:value] = format_money_value(@object.send(method), decimal_separator)
  end

  options[:class] ||= 'form-input'
  options[:inputmode] = 'decimal'
  options[:data] ||= {}
  options[:data][:controller] = 'money-field'
  options[:data][:money_field_locale_value] = locale
  options[:data][:money_field_decimal_separator_value] = decimal_separator
  options[:data][:money_field_thousands_separator_value] = thousands_separator
  options[:data][:action] = 'blur->money-field#format'

  if prepend.present? || append.present?
    options[:class] = 'border-0 focus:ring-0 focus:outline-none text-base grow'
    options[:class] += ' pl-0' if prepend.present?
  end

  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      wrap_with_input_group(@template.text_field(@object_name, method, objectify_options(options)), prepend, append) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_number_field(method, options = {}) ⇒ String

Create a number field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    field options (see #spree_text_field for available options)

Returns:

  • (String)

    HTML string containing the complete form group



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'app/models/spree/admin/form_builder.rb', line 55

def spree_number_field(method, options = {})
  options[:class] ||= 'form-input'
  prepend = options.delete(:prepend)
  append = options.delete(:append)

  if prepend.present? || append.present?
    options[:class] ||= 'border-0 focus:ring-0 focus:outline-none'
  end

  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      wrap_with_input_group(@template.number_field(@object_name, method, objectify_options(options)), prepend, append) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_radio_button(method, tag_value, options = {}) ⇒ String

Create a radio button with Spree custom control styling

Parameters:

  • method (Symbol)

    the field name

  • tag_value (String)

    the value for this radio button option

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

    field options including:

Returns:

  • (String)

    HTML string containing the complete form group with custom radio button



285
286
287
288
289
290
291
292
293
294
295
296
# File 'app/models/spree/admin/form_builder.rb', line 285

def spree_radio_button(method, tag_value, options = {})
  @template.(:div, class: 'form-group') do
    @template.(:div, class: 'custom-control custom-radio') do
      radio = @template.radio_button(@object_name, method, tag_value, objectify_options(options.merge(class: 'custom-control-input form-radio')))
      label_options = { class: 'custom-control-label' }
      label_options[:for] = options[:id] if options[:id]
      label_options[:value] = tag_value unless options[:id]
      label = options[:label] == false ? ''.html_safe : @template.label(@object_name, method, get_label(method, options), label_options)
      radio + label
    end + @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_rich_text_area(method, options = {}) ⇒ String

Create a rich text area (Trix editor) with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    field options (see #spree_text_field for available options)

Returns:

  • (String)

    HTML string containing the complete form group with Trix editor



201
202
203
204
205
206
207
208
209
# File 'app/models/spree/admin/form_builder.rb', line 201

def spree_rich_text_area(method, options = {})
  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      @template.(:div, class: 'trix-container') do
        @template.rich_text_area(@object_name, method, objectify_options(options))
      end +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_select(method, choices = nil, options = {}, html_options = {}, &block) ⇒ String

Create a select field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    options for the select field

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

    field options including:

    • :autocomplete [Boolean] whether to enable autocomplete functionality

    • other options from #spree_text_field

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

    HTML options for the select element

  • block (Proc)

    optional block for generating options

Returns:

  • (String)

    HTML string containing the complete form group



221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'app/models/spree/admin/form_builder.rb', line 221

def spree_select(method, choices = nil, options = {}, html_options = {}, &block)
  if options[:autocomplete]
    html_options[:data] ||= {}
    html_options[:data][:controller] ||= 'autocomplete-select'
  else
    html_options[:class] ||= 'form-select'
  end

  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      @template.select(@object_name, method, choices, objectify_options(options), html_options, &block) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_text_area(method, options = {}) ⇒ String

Create a textarea with Spree form styling and auto-grow functionality

Parameters:

  • method (Symbol)

    the field name

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

    field options including:

    • :class [String] CSS classes (defaults to ‘form-input’)

    • :rows [Integer] number of rows (defaults to 5)

    • :data [Hash] data attributes (defaults to textarea-autogrow controller)

    • other options from #spree_text_field

Returns:

  • (String)

    HTML string containing the complete form group



184
185
186
187
188
189
190
191
192
193
194
# File 'app/models/spree/admin/form_builder.rb', line 184

def spree_text_area(method, options = {})
  @template.(:div, class: 'form-group') do
    options[:class] ||= 'form-input'
    options[:rows] ||= 5
    options[:data] ||= { controller: 'textarea-autogrow' }

    spree_label(method, options) +
      @template.text_area(@object_name, method, objectify_options(options)) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end

#spree_text_field(method, options = {}) ⇒ String

Create a text field with Spree form styling

Parameters:

  • method (Symbol)

    the field name

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

    field options including:

    • :class [String] CSS classes (defaults to ‘form-input’)

    • :label [String, Boolean] label text or false to hide label

    • :required [Boolean] whether field is required

    • :help [String] help text to display below the field

    • :help_bubble [String] help bubble text

    • :prepend [String] text to prepend before the input field

    • :append [String] text to append after the input field

Returns:

  • (String)

    HTML string containing the complete form group



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'app/models/spree/admin/form_builder.rb', line 30

def spree_text_field(method, options = {})
  options[:class] ||= 'form-input'
  prepend = options.delete(:prepend)
  append = options.delete(:append)

  if prepend.present? || append.present?
    options[:class] = 'border-0 focus:ring-0 focus:outline-none text-base grow'

    if prepend.present?
      options[:class] += ' pl-0'
    end
  end

  @template.(:div, class: 'form-group') do
    spree_label(method, options) +
      wrap_with_input_group(@template.text_field(@object_name, method, objectify_options(options)), prepend, append) +
      @template.error_message_on(@object_name, method) + spree_field_help(method, options.merge(class: 'form-text mt-2'))
  end
end