feat(champ.errors): add aria-labelledby error on champs wrapped within a fieldset, make error messages always present and aria-live: assertive on validation error
Co-authored-by: Corinne Durrmeyer <corinne@inseo.fr> Co-authored-by: Colin Darie <colin@darie.eu>
This commit is contained in:
parent
331dfd3044
commit
8453e121d7
6 changed files with 14 additions and 11 deletions
|
@ -34,6 +34,14 @@ module Dsfr
|
||||||
errors.full_messages_for(attribute_or_rich_body)
|
errors.full_messages_for(attribute_or_rich_body)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fieldset_error_opts
|
||||||
|
if dsfr_champ_container == :fieldset && errors_on_attribute?
|
||||||
|
{ aria: { labelledby: "#{describedby_id} #{object.labelledby_id}" } }
|
||||||
|
else
|
||||||
|
{}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# lookup for edge case from `form.rich_text_area`
|
# lookup for edge case from `form.rich_text_area`
|
||||||
|
@ -73,7 +81,6 @@ module Dsfr
|
||||||
'fr-input': true,
|
'fr-input': true,
|
||||||
'fr-mb-0': true
|
'fr-mb-0': true
|
||||||
}.merge(input_error_class_names)))
|
}.merge(input_error_class_names)))
|
||||||
|
|
||||||
if errors_on_attribute?
|
if errors_on_attribute?
|
||||||
@opts.deep_merge!(aria: {
|
@opts.deep_merge!(aria: {
|
||||||
describedby: describedby_id
|
describedby: describedby_id
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
module Dsfr
|
module Dsfr
|
||||||
class InputStatusMessageComponent < ApplicationComponent
|
class InputStatusMessageComponent < ApplicationComponent
|
||||||
def initialize(errors_on_attribute:, error_full_messages:, described_by:, champ:)
|
def initialize(errors_on_attribute:, error_full_messages:, describedby_id:, champ:)
|
||||||
@errors_on_attribute = errors_on_attribute
|
@errors_on_attribute = errors_on_attribute
|
||||||
@error_full_messages = error_full_messages
|
@error_full_messages = error_full_messages
|
||||||
@described_by = described_by
|
@describedby_id = describedby_id
|
||||||
@champ = champ
|
@champ = champ
|
||||||
end
|
end
|
||||||
|
|
||||||
def render?
|
|
||||||
@errors_on_attribute
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.fr-messages-group{ id: @describedby_id }
|
.fr-messages-group{ id: @describedby_id, aria: { live: :assertive } }
|
||||||
- if @error_full_messages.size > 0
|
- if @error_full_messages.size > 0
|
||||||
%p{ class: class_names('fr-message' => true, "fr-message--#{@errors_on_attribute ? 'error' : 'valid'}" => true) }
|
%p{ class: class_names('fr-message' => true, "fr-message--#{@errors_on_attribute ? 'error' : 'valid'}" => true) }
|
||||||
= "« #{@champ.libelle} » "
|
= "« #{@champ.libelle} » "
|
||||||
|
|
|
@ -34,7 +34,7 @@ class EditableChamp::EditableChampComponent < ApplicationComponent
|
||||||
}.merge(champ_component.input_group_error_class_names)
|
}.merge(champ_component.input_group_error_class_names)
|
||||||
),
|
),
|
||||||
data: { controller: stimulus_controller, **data_dependent_conditions, **stimulus_values }
|
data: { controller: stimulus_controller, **data_dependent_conditions, **stimulus_values }
|
||||||
}
|
}.deep_merge(champ_component.fieldset_error_opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fieldset_element_attributes
|
def fieldset_element_attributes
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
|
|
||||||
= render champ_component
|
= render champ_component
|
||||||
|
|
||||||
= render Dsfr::InputStatusMessageComponent.new(errors_on_attribute: champ_component.errors_on_attribute?, error_full_messages: champ_component.error_full_messages, described_by: @champ.describedby_id, champ: @champ)
|
= render Dsfr::InputStatusMessageComponent.new(errors_on_attribute: champ_component.errors_on_attribute?, error_full_messages: champ_component.error_full_messages, describedby_id: @champ.describedby_id, champ: @champ)
|
||||||
|
|
||||||
= @form.hidden_field :id, value: @champ.id
|
= @form.hidden_field :id, value: @champ.id
|
||||||
|
|
|
@ -188,7 +188,7 @@ class Champ < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def describedby_id
|
def describedby_id
|
||||||
"#{html_id}-description" if description.present?
|
"#{html_id}-describedby_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
def log_fetch_external_data_exception(exception)
|
def log_fetch_external_data_exception(exception)
|
||||||
|
|
Loading…
Reference in a new issue