module GOVUKDesignSystemFormBuilder module Elements class Date < Base using PrefixableArray include Traits::Error include Traits::Hint include Traits::Supplemental SEGMENTS = { day: '3i', month: '2i', year: '1i' }.freeze def initialize(builder, object_name, attribute_name, legend:, hint_text:, date_of_birth: false, omit_day:, &block) super(builder, object_name, attribute_name, &block) @legend = legend @hint_text = hint_text @date_of_birth = date_of_birth @omit_day = omit_day end def html Containers::FormGroup.new(@builder, @object_name, @attribute_name).html do Containers::Fieldset.new(@builder, @object_name, @attribute_name, legend: @legend, described_by: [error_id, hint_id, supplemental_id]).html do safe_join( [ supplemental_content.html, hint_element.html, error_element.html, content_tag('div', class: %(#{brand}-date-input)) do safe_join([day, month, year]) end ] ) end end end private def omit_day? @omit_day end def day return nil if omit_day? date_input_item(:day, link_errors: true) end def month date_input_item(:month, link_errors: omit_day?) end def year date_input_item(:year, width: 4) end def date_input_item(segment, width: 2, link_errors: false) value = @builder.object.try(@attribute_name).try(segment) content_tag('div', class: %w(date-input__item).prefix(brand)) do content_tag('div', class: %w(form-group).prefix(brand)) do safe_join( [ tag.label( segment.capitalize, class: date_input_label_classes, for: date_attribute_id(segment, link_errors) ), tag.input( id: date_attribute_id(segment, link_errors), class: date_input_classes(width), name: date_attribute_name(segment), type: 'text', pattern: '[0-9]*', inputmode: 'numeric', value: value, autocomplete: date_of_birth_autocomplete_value(segment) ) ] ) end end end def date_input_classes(width) %w(input date-input__input).prefix(brand).tap do |classes| classes.push(%(#{brand}-input--width-#{width})) classes.push(%(#{brand}-input--error)) if has_errors? end end def date_input_label_classes %w(label date-input__label).prefix(brand) end # if the field has errors we want the govuk_error_summary to # be able to link to the day field. Otherwise, generate IDs # in the normal fashion def date_attribute_id(segment, link_errors) if has_errors? && link_errors field_id(link_errors: link_errors) else [@object_name, @attribute_name, SEGMENTS.fetch(segment)].join("_") end end def date_attribute_name(segment) format( "%s[%s(%s)]", object_name: @object_name, attribute_name: @attribute_name, segment: SEGMENTS.fetch(segment) ) end def date_of_birth_autocomplete_value(segment) return nil unless @date_of_birth { day: 'bday-day', month: 'bday-month', year: 'bday-year' }.fetch(segment) end end end end