demarches-normaliennes/app/components/dsfr/input_component.rb

77 lines
2 KiB
Ruby
Raw Normal View History

class Dsfr::InputComponent < ApplicationComponent
def initialize(form:, attribute:, input_type:, opts: {}, required: true)
@form = form
@attribute = attribute
@input_type = input_type
@opts = opts
@required = required
end
def input_opts
@opts[:class] = class_names(map_array_to_hash_with_true(@opts[:class])
.merge('fr-input': true,
'fr-mb-0': true,
'fr-input--error': errors_on_attribute?))
if errors_on_attribute?
@opts = @opts.deep_merge(aria: {
describedby: error_message_id,
invalid: true
})
end
if @required
@opts[:required] = true
end
@opts
end
# add invalid class on input when input is invalid
# and and valid on input only if another input is invalid
def input_group_class_names
class_names('fr-input-group': true,
"fr-input-group--error": errors_on_attribute?,
"fr-input-group--valid": !errors_on_attribute? && errors_on_another_attribute?)
end
# tried to inline it within the template, but failed miserably with a double render
def label
label = @form.object.class.human_attribute_name(@attribute)
if @required
label += tag.span(" *", class: 'mandatory')
end
label
end
def errors_on_attribute?
@form.object.errors.has_key?(attribute_or_rich_body)
end
def error_message_id
dom_id(@form.object, @attribute)
end
def error_messages
@form.object.errors.full_messages_for(attribute_or_rich_body)
end
private
def errors_on_another_attribute?
!@form.object.errors.empty?
end
def attribute_or_rich_body
case @input_type
when :rich_text_area
@attribute.to_s.sub(/\Arich_/, '').to_sym
else
@attribute
end
end
def map_array_to_hash_with_true(array_or_string_or_nil)
Array(array_or_string_or_nil).to_h { [_1, true] }
end
end