crown_marketplace_utils 0.1.0.beta.2 → 0.1.0.beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -0
  3. data/Gemfile +0 -4
  4. data/Gemfile.lock +44 -29
  5. data/README.md +37 -13
  6. data/crown_marketplace_utils.gemspec +9 -8
  7. data/lib/crown_marketplace_utils/gov_uk_helper/button.rb +2 -0
  8. data/lib/crown_marketplace_utils/gov_uk_helper/details.rb +1 -1
  9. data/lib/crown_marketplace_utils/gov_uk_helper/error_message.rb +1 -1
  10. data/lib/crown_marketplace_utils/gov_uk_helper/field/character_count.rb +190 -0
  11. data/lib/crown_marketplace_utils/gov_uk_helper/field/checkboxes.rb +219 -0
  12. data/lib/crown_marketplace_utils/gov_uk_helper/field/date_input.rb +234 -0
  13. data/lib/crown_marketplace_utils/gov_uk_helper/field/file_upload.rb +125 -0
  14. data/lib/crown_marketplace_utils/gov_uk_helper/field/input.rb +194 -0
  15. data/lib/crown_marketplace_utils/gov_uk_helper/field/radios.rb +219 -0
  16. data/lib/crown_marketplace_utils/gov_uk_helper/field/select.rb +170 -0
  17. data/lib/crown_marketplace_utils/gov_uk_helper/field/textarea.rb +140 -0
  18. data/lib/crown_marketplace_utils/gov_uk_helper/field.rb +305 -0
  19. data/lib/crown_marketplace_utils/gov_uk_helper/fieldset.rb +75 -0
  20. data/lib/crown_marketplace_utils/gov_uk_helper/form_group.rb +0 -3
  21. data/lib/crown_marketplace_utils/gov_uk_helper/header.rb +172 -0
  22. data/lib/crown_marketplace_utils/gov_uk_helper/label.rb +97 -0
  23. data/lib/crown_marketplace_utils/gov_uk_helper/notification_banner.rb +139 -0
  24. data/lib/crown_marketplace_utils/gov_uk_helper/pagination.rb +214 -0
  25. data/lib/crown_marketplace_utils/gov_uk_helper/step_by_step_navigation.rb +225 -0
  26. data/lib/crown_marketplace_utils/gov_uk_helper/tag.rb +39 -0
  27. data/lib/crown_marketplace_utils/gov_uk_helper.rb +32 -0
  28. data/lib/crown_marketplace_utils/version.rb +1 -1
  29. metadata +60 -30
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../field'
4
+
5
+ module CrownMarketplaceUtils
6
+ module GovUkHelper
7
+ module Field
8
+ # = GOV.UK Input
9
+ #
10
+ # This helper is used for generating the input component from the
11
+ # {https://design-system.service.gov.uk/components/text-input GDS - Components - Text Input}
12
+ #
13
+ # This is considered a Field module and so makes use of the methods in {CrownMarketplaceUtils::GovUkHelper::Field}
14
+
15
+ module Input
16
+ include Field
17
+
18
+ # Generates the HTML for the GOV.UK input component
19
+ #
20
+ # @param attribute [String, Symbol] the attribute of the input
21
+ # @param error_message [String] the error message to be displayed
22
+ # @param govuk_input_options [Hash] options that will be used for the parts of the form group, label, hint and input
23
+ #
24
+ # @option govuk_input_options [Hash] :form_group see {govuk_field}
25
+ # @option govuk_input_options [Hash] :label see {govuk_field}
26
+ # @option govuk_input_options [Hash] :hint see {govuk_field}
27
+ # @option govuk_input_options [Hash] :input ({}) the options that will be used when rendering the input.
28
+ # See {govuk_input_field} for more details.
29
+ #
30
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Input
31
+ # which can then be rendered on the page
32
+
33
+ def govuk_input(attribute, error_message = nil, **govuk_input_options)
34
+ govuk_field(:input, attribute, error_message, **govuk_input_options) do |govuk_field_options|
35
+ concat(govuk_input_field(attribute, error_message, **govuk_field_options))
36
+ end
37
+ end
38
+
39
+ # Generates the HTML for the GOV.UK input component using an ActiveModel.
40
+ # Unlike {govuk_input}, the method will be able to automatically determine if the error message needs to be shown.
41
+ #
42
+ # @param model [ActiveModel] model that will be used to find an error message and the value of the input
43
+ # @param attribute [String, Symbol] the attribute of the input
44
+ # @param govuk_input_options [Hash] options that will be used for the parts of the form group, label, hint and input
45
+ #
46
+ # @option (see govuk_input)
47
+ #
48
+ # @return (see govuk_input)
49
+
50
+ def govuk_input_with_model(model, attribute, **govuk_input_options)
51
+ govuk_field_with_model(:input, model, attribute, **govuk_input_options) do |govuk_field_options, error_message|
52
+ govuk_field_options[:value] = model.send(attribute)
53
+
54
+ concat(govuk_input_field(attribute, error_message, **govuk_field_options))
55
+ end
56
+ end
57
+
58
+ # Generates the HTML for the GOV.UK input component using an ActionView::Helpers::FormBuilder.
59
+ # Unlike {govuk_input}, the method will be able to automatically determine if the error message needs to be shown.
60
+ #
61
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the input
62
+ # @param attribute [String, Symbol] the attribute of the input
63
+ # @param govuk_input_options [Hash] options that will be used for the parts of the form group, label, hint and input
64
+ #
65
+ # @option (see govuk_input)
66
+ #
67
+ # @return (see govuk_input)
68
+
69
+ def govuk_input_with_form(form, attribute, **govuk_input_options)
70
+ govuk_field_with_form(:input, form, attribute, **govuk_input_options) do |govuk_field_options, error_message|
71
+ concat(govuk_input_field_with_form(form, attribute, error_message, **govuk_field_options))
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ # Generates the input HTML for {govuk_input} and {govuk_input_with_model}
78
+ #
79
+ # @param attribute [String, Symbol] the attribute of the input
80
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
81
+ # @param govuk_text_input_options [Hash] options that will be used in customising the HTML
82
+ #
83
+ # @option (see _govuk_input_field)
84
+ #
85
+ # @return [ActiveSupport::SafeBuffer] the HTML for the input field which is used in {govuk_input}
86
+
87
+ def govuk_input_field(attribute, error_message, **govuk_text_input_options)
88
+ _govuk_input_field(error_message, **govuk_text_input_options) do |govuk_text_input_classes, govuk_text_input_attributes|
89
+ field_type = :"#{get_field_type(govuk_text_input_options[:field_type])}_tag"
90
+
91
+ send(field_type, attribute, govuk_text_input_options[:value], class: govuk_text_input_classes, **govuk_text_input_attributes)
92
+ end
93
+ end
94
+
95
+ # Generates the input HTML for {govuk_input_with_form}
96
+ #
97
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the input
98
+ # @param attribute [String, Symbol] the attribute of the input
99
+ # @param error_message [String] used to indicate if there is an error which will add an extra classes
100
+ # @param govuk_text_input_options [Hash] options that will be used in customising the HTML
101
+ #
102
+ # @option (see _govuk_input_field)
103
+ #
104
+ # @return [ActiveSupport::SafeBuffer] the HTML for the input field which is used in {govuk_input_with_form}
105
+
106
+ def govuk_input_field_with_form(form, attribute, error_message, **govuk_text_input_options)
107
+ _govuk_input_field(error_message, **govuk_text_input_options) do |govuk_text_input_classes, govuk_text_input_attributes|
108
+ field_type = get_field_type(govuk_text_input_options[:field_type])
109
+
110
+ form.send(field_type, attribute, class: govuk_text_input_classes, **govuk_text_input_attributes)
111
+ end
112
+ end
113
+
114
+ # Wrapper method used by {govuk_input_field} and {govuk_input_field_with_form} to generate the Input HTML
115
+ #
116
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
117
+ # @param govuk_text_input_options [Hash] options that will be used in customising the HTML
118
+ #
119
+ # @option govuk_text_input_options [String] :classes additional CSS classes for the input HTML
120
+ # @option govuk_text_input_options [String] :value (nil) the value of the input
121
+ # @option govuk_text_input_options [Symbol] :field_type the type of the input field, see {get_field_type} for options
122
+ # @option govuk_text_input_options [Hash] :prefix (nil) optional prefix for the input field. See {govuk_fix} for more details.
123
+ # @option govuk_text_input_options [Hash] :suffix (nil) optional suffix for the input field. See {govuk_fix} for more details.
124
+ # @option govuk_text_input_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
125
+ #
126
+ # @yield the input HTML generated by {govuk_input_field} or {govuk_input_field_with_form}
127
+ #
128
+ # @yieldparam govuk_text_input_classes [Array] the classes for the input HTML
129
+ # @yieldparam govuk_text_input_attributes [Hash] additional attributes that will added as part of the HTML
130
+ #
131
+ # @return [ActiveSupport::SafeBuffer] the HTML for the input field which is used in {govuk_input_field} or {govuk_input_field_with_form}
132
+
133
+ def _govuk_input_field(error_message, **govuk_text_input_options)
134
+ govuk_text_input_classes = "govuk-input #{govuk_text_input_options[:classes]}".rstrip
135
+ govuk_text_input_classes << ' govuk-input--error' if error_message
136
+
137
+ govuk_text_input_options[:attributes] ||= {}
138
+
139
+ input_html = yield(govuk_text_input_classes, govuk_text_input_options[:attributes])
140
+
141
+ prefix = govuk_text_input_options[:prefix]
142
+ suffix = govuk_text_input_options[:suffix]
143
+
144
+ if prefix || suffix
145
+ tag.div(class: 'govuk-input__wrapper') do
146
+ capture do
147
+ concat(govuk_fix('pre', prefix)) if prefix
148
+ concat(input_html)
149
+ concat(govuk_fix('suf', suffix)) if suffix
150
+ end
151
+ end
152
+ else
153
+ input_html
154
+ end
155
+ end
156
+
157
+ # Generates the prefix and suffix HTML for {_govuk_input_field}
158
+ #
159
+ # @param fix [String] either +"pre"+ or +"suf"+
160
+ # @param govuk_fix_options [Hash] options that will be used in customising the HTML
161
+ #
162
+ # @option govuk_fix_options [String] :classes additional CSS classes for the input HTML
163
+ # @option govuk_text_input_options [Hash] :attributes ({ aria: { hidden: true } }) any additional attributes that will added as part of the HTML
164
+ #
165
+ # @return [ActiveSupport::SafeBuffer] the HTML for the input field which is used in {govuk_input_field} or {govuk_input_field_with_form}
166
+
167
+ def govuk_fix(fix, govuk_fix_options)
168
+ govuk_fix_classes = ["govuk-input__#{fix}fix"]
169
+ govuk_fix_classes << govuk_fix_options[:classes]
170
+ govuk_fix_options[:attributes] ||= {}
171
+ (govuk_fix_options[:attributes][:aria] ||= {}).merge!({ hidden: true })
172
+
173
+ tag.div(govuk_fix_options[:text], class: govuk_fix_classes, **govuk_fix_options[:attributes])
174
+ end
175
+
176
+ # Returns the field type used to create the rails input tag
177
+ #
178
+ # @param field_type [Symbol] the type of the field, defaults to text
179
+ # Allowed values are:
180
+ # - +:email+
181
+ # - +:password+
182
+
183
+ def get_field_type(field_type)
184
+ case field_type
185
+ when :email, :password
186
+ :"#{field_type}_field"
187
+ else
188
+ :text_field
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,219 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../field'
4
+
5
+ module CrownMarketplaceUtils
6
+ module GovUkHelper
7
+ module Field
8
+ # = GOV.UK Radios
9
+ #
10
+ # This helper is used for generating the radios component from the
11
+ # {https://design-system.service.gov.uk/components/radios GDS - Components - Radios}
12
+ #
13
+ # This is considered a Field module and so makes use of the methods in {CrownMarketplaceUtils::GovUkHelper::Field}
14
+
15
+ module Radios
16
+ include Field
17
+
18
+ # Generates the HTML for the GOV.UK Radios component
19
+ #
20
+ # @param attribute [String, Symbol] the attribute of the raido buttons
21
+ # @param items [Array] array of radio items, see {_govuk_radios_fields}
22
+ # @param error_message [String] the error message to be displayed
23
+ # @param govuk_radios_options [Hash] options that will be used for the parts of the fieldset, form group, hint and radio buttons
24
+ #
25
+ # @option govuk_radios_options [Hash] :form_group see {govuk_fields}
26
+ # @option govuk_radios_options [Hash] :fieldset see {govuk_fields}
27
+ # @option govuk_radios_options [Hash] :hint see {govuk_field}
28
+ # @option govuk_radios_options [Hash] :radios ({}) the options that will be used when rendering the radio buttons.
29
+ # See {govuk_radios_fields} for more details.
30
+ #
31
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Radios
32
+ # which can then be rendered on the page
33
+
34
+ def govuk_radios(attribute, items, error_message = nil, **govuk_radios_options)
35
+ govuk_fields(:radios, attribute, error_message, **govuk_radios_options) do |govuk_field_options|
36
+ concat(govuk_radios_fields(attribute, items, **govuk_field_options))
37
+ end
38
+ end
39
+
40
+ # Generates the HTML for the GOV.UK Radios component using an ActiveModel.
41
+ # Unlike {govuk_radios}, the method will be able to automatically determine if the error message needs to be shown.
42
+ #
43
+ # @param model [ActiveModel] model that will be used to find an error message and the selected radio button
44
+ # @param attribute [String, Symbol] the attribute of the raido buttons
45
+ # @param items [Array] array of radio items, see {_govuk_radios_fields}
46
+ # @param govuk_radios_options [Hash] options that will be used for the parts of the fieldset, form group, hint and radio buttons
47
+ #
48
+ # @option (see govuk_radios)
49
+ #
50
+ # @return (see govuk_radios)
51
+
52
+ def govuk_radios_with_model(model, attribute, items, **govuk_radios_options)
53
+ value = model.send(attribute)
54
+ items.each { |item| item[:checked] = item[:value] == value }
55
+
56
+ govuk_fields_with_model(:radios, model, attribute, **govuk_radios_options) do |govuk_field_options|
57
+ concat(govuk_radios_fields(attribute, items, **govuk_field_options))
58
+ end
59
+ end
60
+
61
+ # Generates the HTML for the GOV.UK Radios component using an ActionView::Helpers::FormBuilder.
62
+ # Unlike {govuk_radios}, the method will be able to automatically determine if the error message needs to be shown.
63
+ #
64
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the radio buttons
65
+ # @param attribute [String, Symbol] the attribute of the raido buttons
66
+ # @param items [Array] array of radio items, see {_govuk_radios_fields}
67
+ # @param govuk_radios_options [Hash] options that will be used for the parts of the fieldset, form group, hint and radio buttons
68
+ #
69
+ # @option (see govuk_radios)
70
+ #
71
+ # @return (see govuk_radios)
72
+
73
+ def govuk_radios_with_form(form, attribute, items, **govuk_radios_options)
74
+ govuk_fields_with_form(:radios, form, attribute, **govuk_radios_options) do |govuk_field_options|
75
+ concat(govuk_radios_fields_with_form(form, attribute, items, **govuk_field_options))
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ # Generates the radios HTML for {govuk_radios}
82
+ #
83
+ # @param attribute [String, Symbol] the attribute of the raido buttons
84
+ # @param items [Array] array of radio items, see {_govuk_radios_fields}
85
+ # @param govuk_radios_options [Hash] options that will be used in customising the HTML
86
+ #
87
+ # @option (see _govuk_radios_fields)
88
+ #
89
+ # @return [ActiveSupport::SafeBuffer] the HTML for the radio buttons which is used in {govuk_radios}
90
+
91
+ def govuk_radios_fields(attribute, items, **govuk_radios_options)
92
+ _govuk_radios_fields(items, **govuk_radios_options) do |radio_item|
93
+ govuk_radio_item(attribute, radio_item)
94
+ end
95
+ end
96
+
97
+ # Generates the radios HTML for {govuk_radios_with_form}
98
+ #
99
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the radio buttons
100
+ # @param attribute [String, Symbol] the attribute of the raido buttons
101
+ # @param items [Array] array of radio items, see {_govuk_radios_fields}
102
+ # @param govuk_radios_options [Hash] options that will be used in customising the HTML
103
+ #
104
+ # @option (see _govuk_radios_fields)
105
+ #
106
+ # @return [ActiveSupport::SafeBuffer] the HTML for the radio buttons which is used in {govuk_radios_with_form}
107
+
108
+ def govuk_radios_fields_with_form(form, attribute, items, **govuk_radios_options)
109
+ _govuk_radios_fields(items, **govuk_radios_options) do |radio_item|
110
+ govuk_radio_item_with_form(form, attribute, radio_item)
111
+ end
112
+ end
113
+
114
+ # Wrapper method used by {govuk_radios_fields} and {govuk_radios_fields_with_form} to generate the radios HTML
115
+ #
116
+ # @param items [Array] array of radio items.
117
+ # Each item is a hash which can be:
118
+ # - +:divider+ text to separate radio items
119
+ # - radio item, see {_govuk_radio_item}
120
+ # @param govuk_radios_options [Hash] options that will be used in customising the HTML
121
+ #
122
+ # @option govuk_radios_options [String] :classes additional CSS classes for the radios HTML
123
+ # @option govuk_radios_options [Hash] :attributes ({ module: 'govuk-radios' }) any additional attributes that will added as part of the HTML
124
+ #
125
+ # @yield the radio item HTML generated by {govuk_radios_fields} or {govuk_radios_fields_with_form}
126
+ #
127
+ # @yieldparam radio_item [Hash] the current radio item to be rendered
128
+ #
129
+ # @return [ActiveSupport::SafeBuffer] the HTML for the radio buttons which is used in {govuk_radios_fields} or {govuk_radios_fields_with_form}
130
+
131
+ def _govuk_radios_fields(items, **govuk_radios_options)
132
+ govuk_radios_classes = ['govuk-radios']
133
+ govuk_radios_classes << govuk_radios_options[:classes]
134
+ ((govuk_radios_options[:attributes] ||= {})[:data] ||= {}).merge!({ module: 'govuk-radios' })
135
+
136
+ tag.div(class: govuk_radios_classes, **govuk_radios_options[:attributes]) do
137
+ capture do
138
+ items.each do |radio_item|
139
+ concat(
140
+ if radio_item[:divider]
141
+ tag.div(radio_item[:divider], class: 'govuk-radios__divider')
142
+ else
143
+ tag.div(class: 'govuk-radios__item') do
144
+ yield(radio_item)
145
+ end
146
+ end
147
+ )
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ # Generates the HTML for a radio button for {govuk_radios_fields_with_form}
154
+ #
155
+ # @param (see _govuk_radio_item)
156
+ #
157
+ # @option (see _govuk_radio_item)
158
+ #
159
+ # @return (see _govuk_radio_item)
160
+
161
+ def govuk_radio_item(attribute, radio_item)
162
+ _govuk_radio_item(attribute, radio_item) do
163
+ label_attribute = radio_item[:attributes][:id] || "#{attribute}[#{radio_item[:value]}]"
164
+
165
+ concat(radio_button_tag(attribute, radio_item[:value], radio_item[:checked], class: 'govuk-radios__input', **radio_item[:attributes]))
166
+ concat(govuk_label(label_attribute, radio_item[:label][:text], **radio_item[:label]))
167
+ end
168
+ end
169
+
170
+ # Generates the HTML for a radio button for {govuk_radios_fields}
171
+ #
172
+ # @param (see _govuk_radio_item)
173
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the radio buttons
174
+ #
175
+ # @option (see _govuk_radio_item)
176
+ #
177
+ # @return (see _govuk_radio_item)
178
+
179
+ def govuk_radio_item_with_form(form, attribute, radio_item)
180
+ _govuk_radio_item(attribute, radio_item) do
181
+ (radio_item[:label][:attributes] ||= {})[:value] = radio_item[:value]
182
+ radio_item[:label][:attributes][:for] = radio_item[:attributes][:id] if radio_item[:attributes][:id]
183
+
184
+ concat(form.radio_button(attribute, radio_item[:value], class: 'govuk-radios__input', **radio_item[:attributes]))
185
+ concat(govuk_label_with_form(form, attribute, radio_item[:label][:text], **radio_item[:label]))
186
+ end
187
+ end
188
+
189
+ # Wrapper method used by {govuk_radio_item} and {govuk_radio_item_with_form} to generate the radios HTML
190
+ # including the label and hint, if there is one.
191
+ #
192
+ # @param attribute [String, Symbol] the attribute of the raido buttons
193
+ # @param radio_item [Hash] the options for the radio item
194
+ #
195
+ # @option radio_item [String] :classes additional CSS classes for the radio button HTML
196
+ # @option radio_item [Hash] :label the parameters that will be used to create the label for the radio button, see {govuk_label}
197
+ # @option radio_item [Hash] :hint (nil) the parameters that will be used to create the hint for the radio button, see {govuk_hint}.
198
+ # If no hint is given then no hint will be rendered
199
+ # @option radio_item [Hash] :attributes ({}) any additional attributes that will be added as part of the radio button HTML
200
+ #
201
+ # @return [ActiveSupport::SafeBuffer] the HTML for the radio buttons, label and hint
202
+ # which is used in {govuk_radio_item} and {govuk_radio_item_with_form}
203
+
204
+ def _govuk_radio_item(attribute, radio_item)
205
+ radio_item[:attributes] ||= {}
206
+ radio_item[:label] ||= {}
207
+ radio_item[:label][:classes] = "govuk-radios__label #{radio_item[:label][:classes]}".rstrip
208
+
209
+ set_item_options_for_hint('radios', attribute, radio_item) if radio_item[:hint]
210
+
211
+ capture do
212
+ yield
213
+ concat(govuk_hint(radio_item[:hint][:text], **radio_item[:hint])) if radio_item[:hint]
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
219
+ end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'action_view'
4
+ require_relative '../field'
5
+
6
+ module CrownMarketplaceUtils
7
+ module GovUkHelper
8
+ module Field
9
+ # = GOV.UK Select
10
+ #
11
+ # This helper is used for generating the select component from the
12
+ # {https://design-system.service.gov.uk/components/select GDS - Components - Select}
13
+ #
14
+ # This is considered a Field module and so makes use of the methods in {CrownMarketplaceUtils::GovUkHelper::Field}
15
+
16
+ module Select
17
+ include ActionView::Helpers::FormOptionsHelper
18
+ include Field
19
+
20
+ # Generates the HTML for the GOV.UK Select component
21
+ #
22
+ # @param attribute [String, Symbol] the attribute of the select field
23
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
24
+ # @param error_message [String] the error message to be displayed
25
+ # @param govuk_select_options [Hash] options that will be used for the parts of the form group, label, hint and select
26
+ #
27
+ # @option govuk_select_options [Hash] :form_group see {govuk_field}
28
+ # @option govuk_select_options [Hash] :label see {govuk_field}
29
+ # @option govuk_select_options [Hash] :hint see {govuk_field}
30
+ # @option govuk_select_options [Hash] :select ({}) the options that will be used when rendering the select field.
31
+ # See {govuk_select_field} for more details.
32
+ #
33
+ # @return [ActiveSupport::SafeBuffer] the HTML for the GOV.UK Select
34
+ # which can then be rendered on the page
35
+
36
+ def govuk_select(attribute, items, error_message = nil, **govuk_select_options)
37
+ govuk_field(:select, attribute, error_message, **govuk_select_options) do |govuk_field_options|
38
+ concat(govuk_select_field(attribute, items, error_message, **govuk_field_options))
39
+ end
40
+ end
41
+
42
+ # Generates the HTML for the GOV.UK Select component using an ActiveModel.
43
+ # Unlike {govuk_select}, the method will be able to automatically determine if the error message needs to be shown.
44
+ #
45
+ # @param model [ActiveModel] model that will be used to find an error message and the selected options
46
+ # @param attribute [String, Symbol] the attribute of the select field
47
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
48
+ # @param govuk_select_options [Hash] options that will be used for the parts of the form group, label, hint and select
49
+ #
50
+ # @option see govuk_select)
51
+ #
52
+ # @return (see govuk_select)
53
+
54
+ def govuk_select_with_model(model, attribute, items, **govuk_select_options)
55
+ (govuk_select_options[:select] ||= {})[:selected] = model.send(attribute)
56
+
57
+ govuk_field_with_model(:select, model, attribute, **govuk_select_options) do |govuk_field_options, error_message|
58
+ concat(govuk_select_field(attribute, items, error_message, **govuk_field_options))
59
+ end
60
+ end
61
+
62
+ # Generates the HTML for the GOV.UK Select component using an ActionView::Helpers::FormBuilder.
63
+ # Unlike {govuk_select}, the method will be able to automatically determine if the error message needs to be shown.
64
+ #
65
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the select field
66
+ # @param attribute [String, Symbol] the attribute of the select field
67
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
68
+ # @param govuk_select_options [Hash] options that will be used for the parts of the form group, label, hint and select
69
+ #
70
+ # @option see govuk_select)
71
+ #
72
+ # @return (see govuk_select)
73
+
74
+ def govuk_select_with_form(form, attribute, items, **govuk_select_options)
75
+ govuk_field_with_form(:select, form, attribute, **govuk_select_options) do |govuk_field_options, error_message|
76
+ concat(govuk_select_field_with_form(form, attribute, items, error_message, **govuk_field_options))
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ # Generates the select HTML for {govuk_select}
83
+ #
84
+ # @param attribute [String, Symbol] the attribute of the select field
85
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
86
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
87
+ # @param govuk_select_options [Hash] options that will be used in customising the HTML
88
+ #
89
+ # @option (see set_govuk_select_field_options)
90
+ #
91
+ # @return [ActiveSupport::SafeBuffer] the HTML for the select field which is used in {govuk_select}
92
+
93
+ def govuk_select_field(attribute, items, error_message, **govuk_select_options)
94
+ set_govuk_select_field_options(error_message, govuk_select_options)
95
+
96
+ select_tag(
97
+ attribute,
98
+ options_for_select(
99
+ govuk_map_select_items(items),
100
+ govuk_select_options[:selected]
101
+ ),
102
+ class: govuk_select_options[:classes],
103
+ **govuk_select_options[:attributes]
104
+ )
105
+ end
106
+
107
+ # Generates the select HTML for {govuk_select_with_form}
108
+ #
109
+ # @param form [ActionView::Helpers::FormBuilder] the form builder used to create the select field
110
+ # @param attribute [String, Symbol] the attribute of the select field
111
+ # @param items [Array] array of option items for the select, see {govuk_map_select_items}
112
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
113
+ # @param govuk_select_options [Hash] options that will be used in customising the HTML
114
+ #
115
+ # @option (see set_govuk_select_field_options)
116
+ #
117
+ # @return [ActiveSupport::SafeBuffer] the HTML for the select field which is used in {govuk_select_with_form}
118
+
119
+ def govuk_select_field_with_form(form, attribute, items, error_message, **govuk_select_options)
120
+ set_govuk_select_field_options(error_message, govuk_select_options)
121
+
122
+ form.select(
123
+ attribute,
124
+ govuk_map_select_items(items),
125
+ govuk_select_options[:select] || {},
126
+ class: govuk_select_options[:classes],
127
+ **govuk_select_options[:attributes]
128
+ )
129
+ end
130
+
131
+ # Initialises the attributes for the select input
132
+ #
133
+ # @param error_message [String] used to indicate if there is an error which will add extra classes
134
+ # @param govuk_select_options [Hash] options that will be used in customising the HTML
135
+ #
136
+ # @option govuk_select_options [String] :classes additional CSS classes for the select HTML
137
+ # @option govuk_select_options [String] :selected (nil) the selected option
138
+ # @option govuk_select_options [Hash] :attributes ({}) any additional attributes that will added as part of the HTML
139
+
140
+ def set_govuk_select_field_options(error_message, govuk_select_options)
141
+ govuk_select_options[:classes] = "govuk-select #{govuk_select_options[:classes]}".rstrip
142
+ govuk_select_options[:classes] << ' govuk-select--error' if error_message
143
+ govuk_select_options[:attributes] ||= {}
144
+ end
145
+
146
+ # Maps the items into an array that can be used to generate the options for
147
+ # {govuk_select_field} and {govuk_select_field_with_form}
148
+ #
149
+ # @param items [Array] array of option items for the select
150
+ #
151
+ # @option items [String] :text the text of the option item.
152
+ # If this is blank the value is used
153
+ # @option items [String] :value the value of the option item
154
+ # @option items [Hash] :attributes ({}) any additional attributes that will added as part of the option HTML
155
+ #
156
+ # @return [Array] array of option params that are used in {govuk_select_field} and {govuk_select_field_with_form}
157
+
158
+ def govuk_map_select_items(items)
159
+ items.map do |item|
160
+ [
161
+ item[:text] || item[:value],
162
+ item[:value],
163
+ (item[:attributes] || {})
164
+ ]
165
+ end
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end