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

Sign up to get free protection for your applications and to get access to all the features.
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