Class: DesignSystem::Govuk::FormBuilder

Inherits:
DesignSystem::Generic::FormBuilder show all
Includes:
GOVUKDesignSystemFormBuilder::Builder
Defined in:
lib/design_system/govuk/form_builder.rb

Overview

The Govuk version of the form builder

Direct Known Subclasses

Nhsuk::FormBuilder

Instance Method Summary collapse

Methods inherited from DesignSystem::Generic::FormBuilder

brand

Methods included from Helpers::CssHelper

#css_class_options_merge

Constructor Details

#initialize(object_name, object, template, options) ⇒ FormBuilder

Returns a new instance of FormBuilder.



10
11
12
13
14
15
# File 'lib/design_system/govuk/form_builder.rb', line 10

def initialize(object_name, object, template, options)
  object_name = object_name.to_s if object_name.is_a?(Symbol)
  super

  config.brand = self.class.brand
end

Instance Method Details

#ds_check_box(method, options = {}, checked_value = '1', unchecked_value = '0') ⇒ Object

Same interface as ActionView::Helpers::FormHelper.check_box, but with label automatically added.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/design_system/govuk/form_builder.rb', line 21

def ds_check_box(method, options = {}, checked_value = '1', unchecked_value = '0')
  value = checked_value == '1' ? true : checked_value
  unchecked_value = false if unchecked_value == '0'

  # First try to find a custom translation for this specific value
  # If no custom translation provided, fall back to the default value
  custom_translation = translated_label_for_value(method, value)
  label = if custom_translation.include?('Translation missing')
            optional_label(value, options)
          else
            optional_label(value, options, custom_translation)
          end

  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # link_errors [Boolean] controls whether this radio button should be linked to from {#govuk_error_summary}
  # exclusive [Boolean] sets the checkbox so that when checked none of its siblings can be too. Usually
  #   used for the 'None of these apply to me' option found beneath a {#govuk_check_box_divider}.
  govuk_check_box(method, value, unchecked_value, hint:, label:, link_errors: false, multiple: true,
                                                  exclusive: false, **options)
end

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



44
45
46
47
48
49
50
51
52
# File 'lib/design_system/govuk/form_builder.rb', line 44

def ds_check_boxes_fieldset(method, options = {}, &)
  legend = optional_legend(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # multiple [Boolean] controls whether the check box is part of a collection or represents a single attribute
  govuk_check_boxes_fieldset(method,
                             legend:, caption: {}, hint:, small: false, form_group: {}, multiple: true, **options, &)
end

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

Same interface as ActionView::Helpers::FormOptionsHelper.collection_check_boxes, but with legend automatically added.



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/design_system/govuk/form_builder.rb', line 55

def ds_collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {},
                              &)
  legend = optional_legend(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint
  hint_method = options.delete(:hint_method)
  caption = options.delete(:caption) || {}
  form_group = options.delete(:form_group) || {}
  include_hidden = options.delete(:include_hidden) || config.default_collection_check_boxes_include_hidden

  govuk_collection_check_boxes(method, collection, value_method, text_method, hint_method, hint:, legend:,
                                                                                           caption:, small: false, form_group:, include_hidden:, **html_options, &)
end

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

Same interface as ActionView::Helpers::FormOptionsHelper.collection_radio_buttons, but with legend automatically added.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/design_system/govuk/form_builder.rb', line 70

def ds_collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &)
  hint = options.delete(:hint)
  hint = { text: hint } if hint
  hint_method = options.delete(:hint_method)
  bold_labels = options.delete(:bold_labels)
  caption = options.delete(:caption) || {}
  form_group = options.delete(:form_group) || {}
  include_hidden = options.delete(:include_hidden) || true
  legend = optional_legend(method, options)

  # value_method [Symbol, Proc] The method called against each member of the collection to provide the value.
  #   When a +Proc+ is provided it must take a single argument that is a single member of the collection
  # text_method [Symbol, Proc, nil] The method called against each member of the collection to provide the label text.
  #   When a +Proc+ is provided it must take a single argument that is a single member of the collection.
  #   When a +nil+ value is provided the label text will be retrieved from the locale.
  # hint_method [Symbol, Proc, nil] The method called against each member of the collection to provide the hint text.
  #   When a +Proc+ is provided it must take a single argument that is a single member of the collection.
  #   When a +nil+ value is provided the hint text will be retrieved from the locale. This is the default and param can be omitted.
  # legend [NilClass,Hash,Proc] options for configuring the legend. Legend will be omitted if +nil+.
  # inline [Boolean] controls whether the radio buttons are displayed inline or not
  # small [Boolean] controls whether small radio buttons are used instead of regular-sized ones
  # bold_labels [Boolean] controls whether the radio button labels are bold
  # include_hidden [Boolean] controls whether a hidden field is inserted to allow for empty submissions
  # legend text [String] the fieldset legend's text content
  # legend size [String] the size of the fieldset legend font, can be +xl+, +l+, +m+ or +s+
  # legend tag [Symbol,String] the tag used for the fieldset's header, defaults to +h1+.
  # legend hidden [Boolean] control the visibility of the legend. Hidden legends will still be read by screenreaders
  # legend kwargs [Hash] additional arguments are applied as attributes on the +legend+ element
  govuk_collection_radio_buttons(method, collection, value_method, text_method, hint_method:, hint:, legend:,
                                                                                caption:, inline: false, small: false, bold_labels:, include_hidden:, form_group:, **html_options, &)
end

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

Same interface as ActionView::Helpers::FormOptionsHelper.collection_select, but with label automatically added. label, hint, caption and form_group should be provided as options rather than html_options



104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/design_system/govuk/form_builder.rb', line 104

def ds_collection_select(method, collection, value_method, text_method, options = {}, html_options = {})
  label = optional_label(method, options)

  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # attribute_name [Symbol] The name of the attribute
  # collection [Enumerable<Object>] Options to be added to the +select+ element
  # value_method [Symbol] The method called against each member of the collection to provide the value
  # text_method [Symbol] The method called against each member of the collection to provide the text
  # options (rails_options) [Hash] Options hash passed through to Rails' +collection_select+ helper
  govuk_collection_select(method, collection, value_method, text_method, options:, hint:, label:,
                                                                         caption: {}, form_group: {}, **html_options)
end

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

Same interface as ActionView::Helpers::FormHelper.date_field, but with label automatically added.



120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/design_system/govuk/form_builder.rb', line 120

def ds_date_field(method, options = {})
  legend = optional_legend(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # omit_day [Boolean] do not render a day input, only capture month and year
  # maxlength_enabled [Boolean] adds maxlength attribute to day, month and year inputs (2, 2, and 4, respectively)
  # segments [Hash] allows Rails' multiparameter attributes to be overridden on a field-by-field basis. Hash must
  #   contain +day:+, +month:+ and +year:+ keys. Defaults to the default value set in the +default_date_segments+ setting in {GOVUKDesignSystemFormBuilder.DEFAULTS}
  # date_of_birth [Boolean] if +true+ {https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values birth date auto completion attributes}
  #   will be added to the inputs
  govuk_date_field(method, hint:, legend:, caption: {}, date_of_birth: false, omit_day: false,
                           maxlength_enabled: false, segments: config.default_date_segments, form_group: {}, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.email_field, but with label automatically added.



136
137
138
139
140
141
142
143
# File 'lib/design_system/govuk/form_builder.rb', line 136

def ds_email_field(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  govuk_email_field(method, hint:, label:, caption: {}, width: nil, extra_letter_spacing: false, form_group: {},
                            prefix_text: nil, suffix_text: nil, **options)
end

#ds_error_summary(title = nil, options = nil) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/design_system/govuk/form_builder.rb', line 145

def ds_error_summary(title = nil, options = nil)
  title, options = separate_content_or_options(title, options)
  title ||= I18n.t('activerecord.errors.title')

  # title [String] the error summary heading
  # link_base_errors_to [Symbol,String] set the field that errors on +:base+ are linked
  #   to, as there won't be a field representing the object base.
  # order [Array<Symbol>] the attribute order in which error messages are displayed. Ordered
  #   attributes will appear first and unordered ones will be last, sorted in the default manner (in
  #   which they were defined on the model).
  # kwargs [Hash] kwargs additional arguments are applied as attributes to the error summary +div+ element
  # block [Block] arbitrary HTML that will be rendered between title and error message list
  # presenter [Class,Object] the class or object that is responsible for formatting a list of error
  #   messages that will be rendered in the summary.
  govuk_error_summary(title, presenter: config.default_error_summary_presenter, link_base_errors_to: nil,
                             order: nil, **options)
end

#ds_field_set_tag(legend = nil, options = nil) ⇒ Object

Same interface as ActionView::Helpers::FormHelper.field_set_tag, but with legend and fieldset tags automatically added.



164
165
166
167
168
169
170
171
# File 'lib/design_system/govuk/form_builder.rb', line 164

def ds_field_set_tag(legend = nil, options = nil, &)
  options ||= {}
  legend_options = options.delete(:legend) || {}
  custom_translation = I18n.t('helpers.fieldset.legend')
  legend = { text: legend || custom_translation }.merge(legend_options)

  govuk_fieldset(legend:, caption: {}, described_by: nil, **options, &)
end

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

Same interface as ActionView::Helpers::FormHelper.file_field, but with label automatically added



174
175
176
177
178
179
180
181
# File 'lib/design_system/govuk/form_builder.rb', line 174

def ds_file_field(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # javascript [Boolean] Configures whether to add HTML for the javascript-enhanced version of the component
  govuk_file_field(method, label:, caption: {}, hint:, form_group: {}, javascript: false, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.hidden_field, but with label automatically added and takes a show_text option



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/design_system/govuk/form_builder.rb', line 184

def ds_hidden_field(method, options = {})
  @brand = config.brand

  options[:class] = Array(options[:class])
  options[:class] << "#{@brand}-visually-hidden"

  label_hash = options.delete(:label) || {}
  label = ds_label(method, label_hash)
  show_text = options.delete(:show_text)

  (:div, class: "#{@brand}-form-group") do
    components = []
    components << label if label
    components << hidden_field(method, **options)
    components << (:span, show_text, class: "#{@brand}-body-m") if show_text

    safe_join(components)
  end
end

#ds_label(method, content_or_options = nil, options = nil) ⇒ Object

Same interface as ActionView::Helpers::FormHelper.label



205
206
207
208
209
210
211
212
213
214
# File 'lib/design_system/govuk/form_builder.rb', line 205

def ds_label(method, content_or_options = nil, options = nil, &)
  content, options = separate_content_or_options(content_or_options, options)
  text = content || translated_label(method)

  # size [String] the size of the label font, can be +xl+, +l+, +m+, +s+ or nil
  # tag [Symbol,String] the label's wrapper tag, intended to allow labels to act as page headings
  # hidden [Boolean] control the visability of the label. Hidden labels will stil be read by screenreaders
  # kwargs [Hash] additional arguments are applied as attributes on the +label+ element
  govuk_label(method, text:, size: nil, hidden: false, tag: nil, caption: nil, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.number_field, but with label automatically added.



217
218
219
220
221
222
223
224
# File 'lib/design_system/govuk/form_builder.rb', line 217

def ds_number_field(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  govuk_number_field(method, hint:, label:, caption: {}, width: nil, extra_letter_spacing: false, form_group: {},
                             prefix_text: nil, suffix_text: nil, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.password_field, but with label automatically added.



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/design_system/govuk/form_builder.rb', line 227

def ds_password_field(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # caption [Hash] configures or sets the caption content which is inserted above the label
  # caption text [String] the caption text
  # caption size [String] the size of the caption, can be +xl+, +l+ or +m+. Defaults to +m+
  # caption kwargs [Hash] additional arguments are applied as attributes on the caption +span+ element
  # kwargs [Hash] kwargs additional arguments are applied as attributes to the +input+ element
  # form_group [Hash] configures the form group
  # form_group kwargs [Hash] additional attributes added to the form group
  # show_password_text [String] button text when the password is hidden. Defaults to "Show"
  # hide_password_text [String] button text when the password is shown. Defaults to "Hide"
  # show_password_aria_label_text [String] button text exposed to assistive technologies, like screen readers,
  # when the password is hidden. Defaults to "Show password"
  # hide_password_aria_label_text [String] button text exposed to assistive technologies, like screen readers,
  # when the password is visible. Defaults to "Hide password"
  # password_shown_announcement_text [String] Announcement made to screen reader users when their password has
  # become visible in plain text. Defaults to "Your password is visible"
  # password_hidden_announcement_text [String] Announcement made to screen reader users when their password has
  # been obscured and is not visible. Defaults to "Your password is hidden"
  govuk_password_field(method, hint:, label:, caption: {}, form_group: {}, show_password_text: nil,
                               hide_password_text: nil, show_password_aria_label_text: nil,
                               hide_password_aria_label_text: nil, password_shown_announcement_text: nil,
                               password_hidden_announcement_text: nil, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.phone_field, but with label automatically added.



256
257
258
259
260
261
262
263
# File 'lib/design_system/govuk/form_builder.rb', line 256

def ds_phone_field(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  govuk_phone_field(method, hint:, label:, caption: {}, width: nil, extra_letter_spacing: false, form_group: {},
                            prefix_text: nil, suffix_text: nil, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.radio_button, but with label automatically added.



266
267
268
269
270
271
272
# File 'lib/design_system/govuk/form_builder.rb', line 266

def ds_radio_button(method, tag_value, options = {})
  label = optional_label(tag_value, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  govuk_radio_button(method, tag_value, hint:, label:, link_errors: false, **options)
end

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



274
275
276
277
278
279
280
281
# File 'lib/design_system/govuk/form_builder.rb', line 274

def ds_radio_buttons_fieldset(method, options = {}, &)
  legend = optional_legend(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  govuk_radio_buttons_fieldset(method,
                               hint:, legend:, caption: {}, inline: false, small: false, form_group: {}, **options, &)
end

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

Same interface as ActionView::Helpers::FormOptionsHelper.select, but with label automatically added. label, hint, caption and form_group should be provided as options rather than html_options



285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/design_system/govuk/form_builder.rb', line 285

def ds_select(method, choices = nil, options = {}, html_options = {}, &)
  choices, options, html_options = separate_choices_or_options(choices, options, html_options)

  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # choices [Array,Hash] The +option+ values, usually provided via
  #   the +options_for_select+ or +grouped_options_for_select+ helpers.
  # if it's not specified, an empty select element will be created
  # example: form.ds_select :department_id, { options }
  govuk_select(method, choices, options:, label:, hint:, form_group: {}, caption: {}, **html_options, &)
end

#ds_submit(value = nil, **options) ⇒ Object

Same interface as ActionView::Helpers::FormBuiler.submit, but with label automatically added.



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/design_system/govuk/form_builder.rb', line 300

def ds_submit(value = nil, **options)
  # text [String,Proc] the button text. When a +Proc+ is provided its contents will be rendered within the button element
  # type [Symbol] the type of submit button, can be :secondary, :warning. The button is a primary button if unspecified
  # inverse [Boolean] inverts the colours of the button. Note this isn't yet part of the design system.
  # prevent_double_click [Boolean] adds JavaScript to safeguard the
  #   form from being submitted more than once
  # validate [Boolean] adds the formnovalidate to the submit button when true, this disables all
  #   client-side validation provided by the browser. This is to provide a more consistent and accessible user
  #   experience
  # disabled [Boolean] makes the button disabled when true
  # kwargs [Hash] kwargs additional arguments are applied as attributes to the +button+ element
  # block [Block] When content is passed in via a block the submit element and the block content will
  #   be wrapped in a +<div class="govuk-button-group">+ which will space the buttons and links within
  #   evenly.
  type = options.delete(:type)
  warning = type == :warning
  secondary = type == :secondary

  govuk_submit(text = value || config.default_submit_button_text, warning:, secondary:, inverse: false, prevent_double_click: true,
                                                                  validate: config.default_submit_validate, disabled: false, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.text_area, but with label automatically added.



323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/design_system/govuk/form_builder.rb', line 323

def ds_text_area(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # max_words [Integer] adds the GOV.UK max word count
  # max_chars [Integer] adds the GOV.UK max characters count
  # threshold [Integer] only show the +max_words+ and +max_chars+ warnings once a threshold (percentage) is reached
  # rows [Integer] sets the initial number of rows
  govuk_text_area(method, hint:, label:, caption: {}, max_words: nil, max_chars: nil, rows: 5, threshold: nil,
                          form_group: {}, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.text_field, but with label automatically added.



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/design_system/govuk/form_builder.rb', line 337

def ds_text_field(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  # width [Integer,String] sets the width of the input, can be +2+, +3+ +4+, +5+, +10+ or +20+ characters
  #   or +one-quarter+, +one-third+, +one-half+, +two-thirds+ or +full+ width of the container
  # extra_letter_spacing [Boolean] when true adds space between characters to increase the readability of
  #   sequences of letters and numbers. Defaults to +false+.
  # caption [Hash] configures or sets the caption content which is inserted above the label
  # caption text [String] the caption text
  # caption size [String] the size of the caption, can be +xl+, +l+ or +m+. Defaults to +m+
  # caption kwargs [Hash] additional arguments are applied as attributes on the caption +span+ element
  # form_group [Hash] configures the form group
  # form_group kwargs [Hash] additional attributes added to the form group
  # prefix_text [String] the text placed before the input. No prefix will be added if left +nil+
  # suffix_text [String] the text placed after the input. No suffix will be added if left +nil+
  # block [Block] arbitrary HTML that will be rendered between the hint and the input
  govuk_text_field(method, hint:, label:, caption: {}, width: nil, extra_letter_spacing: false,
                           form_group: {}, prefix_text: nil, suffix_text: nil, **options)
end

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

Same interface as ActionView::Helpers::FormHelper.url_field, but with label automatically added.



360
361
362
363
364
365
366
367
# File 'lib/design_system/govuk/form_builder.rb', line 360

def ds_url_field(method, options = {})
  label = optional_label(method, options)
  hint = options.delete(:hint)
  hint = { text: hint } if hint

  govuk_url_field(method, hint:, label:, caption: {}, width: nil, extra_letter_spacing: false, form_group: {},
                          prefix_text: nil, suffix_text: nil, **options)
end