class GovukElementsFormBuilder < ActionView::Helpers::FormBuilder attr_reader :template, :object_name def text_area(method, **options) with_label(method) { super(method, add_class(options, 'text form-control')) } end def bold_label(method, text: nil, **options) label(method, text, add_class(options, 'form-label')) end def radio_buttons(method, values, labeler: labeler, **options) radio_button_fieldset(method, options) { with_label(method) { values.map { |value| label(method, value: value, class: 'block-label') { radio_button(method, value) + labeler.call(value) } }.join.html_safe } } end def text_field(method, **options) with_label(method) { super(method, add_class(options, 'form-control')) } end def password_field(method, **options) with_label(method) { super(method, add_class(options, 'form-control')) } end def file_field(method, **options) with_label(method) { super(method, add_class(options, 'form-control')) } end def collection_select(method, values, valuer: nil, labeler: nil, **options) valuer ||= ->(a) { a.respond_to?(:to_param) ? a.to_param : a } labeler ||= ->(a) { a } with_label(method) { super( method, values, valuer, labeler, options, class: 'select form-control' ) } end def button(value = nil, **options) super(value, add_class(options, 'button')) end def with_label(method, &content) error_messages = object.errors[method].map { |error| template.content_tag(:p, class: 'error') { error } }.join.html_safe bold_label(method) + content.call + error_messages end def add_class(options, klass) options.merge(class: [options[:class], klass].compact.join(' ')) end private def radio_button_fieldset(method, options, &blk) id = [object_name, method].join('_') klass = options[:inline] ? 'inline' : '' template.content_tag(:fieldset, id: id, class: klass, &blk) end end