Merge pull request #9839 from mfo/US/fix-filter-focus-out-with-not-selected-filter

correctif : ETQ instructeurs, lorsque je sors du composant de filtrage sans choisir une option, le site renvoie une erreur
This commit is contained in:
Colin Darie 2023-12-21 08:42:12 +00:00 committed by GitHub
commit e17c3bd046
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 36 additions and 21 deletions

View file

@ -1,6 +1,7 @@
exclude:
- 'app/assets/stylesheets/reset.scss'
- 'app/assets/stylesheets/direct_uploads.scss'
- 'app/assets/stylesheets/dsfr_override.scss'
linters:
BangFormat:

View file

@ -33,6 +33,10 @@ trix-editor.fr-input {
width: 100%;
}
}
.fr-autocomplete {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.031 16.6168L22.3137 20.8995L20.8995 22.3137L16.6168 18.031C15.0769 19.263 13.124 20 11 20C6.032 20 2 15.968 2 11C2 6.032 6.032 2 11 2C15.968 2 20 6.032 20 11C20 13.124 19.263 15.0769 18.031 16.6168ZM16.0247 15.8748C17.2475 14.6146 18 12.8956 18 11C18 7.1325 14.8675 4 11 4C7.1325 4 4 7.1325 4 11C4 14.8675 7.1325 18 11 18C12.8956 18 14.6146 17.2475 15.8748 16.0247L16.0247 15.8748Z'%3E%3C/path%3E%3C/svg%3E");
}
}
@media (max-width: 62em) {

View file

@ -1,7 +1,11 @@
= form_tag add_filter_instructeur_procedure_path(procedure), method: :post, class: 'dropdown-form large', id: 'filter-component', data: { turbo: true, controller: 'autosubmit' } do
.fr-select-group
= label_tag :field, t('.column'), class: 'fr-label fr-m-0', id: 'instructeur-filter-combo-label', for: 'search-filter'
= render Dsfr::ComboboxComponent.new form: nil, name: :field, options: filterable_fields_for_select, selected: field_id, id: 'search-filter', class: 'fr-select', describedby: 'instructeur-filter-combo-label', allows_custom_value: false, allows_blank: false, form_id: 'filter-component', data: { no_autosubmit: ['input', 'blur'].join(' '), no_autosubmit_on_empty: "true" }
= render Dsfr::ComboboxComponent.new form: nil,
options: filterable_fields_for_select,
selected: field_id,
input_html_options: { name: :field, id: 'search-filter', class: 'fr-select', describedby: 'instructeur-filter-combo-label', allows_custom_value: false, form_id: 'filter-component' },
hidden_html_options: { data: { no_autosubmit: ['input', 'blur'].join(' '), no_autosubmit_on_empty: "true", autosubmit_target: 'input' } }
%input.hidden{ type: 'submit', formaction: update_filter_instructeur_procedure_path(procedure), data: { autosubmit_target: 'submitter' } }

View file

@ -1,6 +1,6 @@
class Dsfr::ComboboxComponent < ApplicationComponent
def initialize(form: nil, options: nil, url: nil, selected: nil, allows_custom_value: false, **html_options)
@form, @options, @url, @selected, @allows_custom_value, @html_options = form, options, url, selected, allows_custom_value, html_options
def initialize(form: nil, options: nil, url: nil, selected: nil, allows_custom_value: false, input_html_options: {}, hidden_html_options: {})
@form, @options, @url, @selected, @allows_custom_value, @input_html_options, @hidden_html_options = form, options, url, selected, allows_custom_value, input_html_options, hidden_html_options
end
attr_reader :form, :options, :url, :selected, :allows_custom_value
@ -8,11 +8,11 @@ class Dsfr::ComboboxComponent < ApplicationComponent
private
def name
@html_options[:name]
@input_html_options[:name]
end
def form_id
@html_options[:form_id]
@input_html_options[:form_id]
end
def html_input_options
@ -23,18 +23,21 @@ class Dsfr::ComboboxComponent < ApplicationComponent
id: input_id,
class: input_class,
role: 'combobox',
data: @html_options[:data],
'aria-expanded': 'false',
'aria-describedby': @html_options[:describedby]
'aria-describedby': @input_html_options[:describedby]
}.compact
end
def input_id
@html_options[:id]
@input_html_options[:id]
end
def input_class
"#{@html_options[:class].presence || ''} fr-select"
class_names(
"#{@input_html_options[:class]}": @input_html_options[:class].presence,
'fr-select': true,
'fr-autocomplete': @url.presence
)
end
def selected_option_label_input_value

View file

@ -2,9 +2,9 @@
.fr-ds-combobox-input
%input{ value: selected_option_label_input_value, **html_input_options }
- if form
= form.hidden_field name, value: selected_option_value_input_value, form: form_id, data: html_input_options[:data]
= form.hidden_field name, value: selected_option_value_input_value, form: form_id, **@hidden_html_options
- else
%input{ type: 'hidden', name: name, value: selected_option_value_input_value, form: form_id, data: html_input_options[:data] }
%input{ type: 'hidden', name: name, value: selected_option_value_input_value, form: form_id, **@hidden_html_options }
.fr-menu
%ul.fr-menu__list.hidden{ role: 'listbox', hidden: true, id: list_id, data: { turbo_force: :browser, options: options_json, url:, hints: hints_json }.compact }
.sr-only{ aria: { live: 'polite', atomic: 'true' }, data: { turbo_force: :browser } }

View file

@ -1,2 +1,2 @@
= render Dsfr::ComboboxComponent.new form: @form, name: :value, url: data_sources_data_source_adresse_path, selected: @champ.value, id: @champ.input_id, class: 'fr-select', describedby: @champ.describedby_id, allows_custom_value: true do
= render Dsfr::ComboboxComponent.new form: @form, url: data_sources_data_source_adresse_path, selected: @champ.value, allows_custom_value: true, input_html_options: { name: :value, id: @champ.input_id, class: 'fr-select', describedby: @champ.describedby_id } do
= @form.hidden_field :external_id, data: { value_slot: 'value' }

View file

@ -1,2 +1,2 @@
= render Dsfr::ComboboxComponent.new form: @form, name: :external_id, url: data_sources_data_source_commune_path, selected: [@champ.to_s, @champ.selected], id: @champ.input_id, class: 'fr-select', describedby: @champ.describedby_id do
= render Dsfr::ComboboxComponent.new form: @form, url: data_sources_data_source_commune_path, selected: [@champ.to_s, @champ.selected], input_html_options: { name: :external_id, id: @champ.input_id, class: 'fr-select', describedby: @champ.describedby_id } do
= @form.hidden_field :code_postal, data: { value_slot: 'data:string' }

View file

@ -18,7 +18,7 @@
%label.fr-label{ for: "#{@champ.id}_radio_option_other" }
= t('shared.champs.drop_down_list.other')
- elsif @champ.render_as_combobox?
= render Dsfr::ComboboxComponent.new form: @form, name: :value, options: @champ.enabled_non_empty_options(other: true), selected: @champ.selected, id: @champ.input_id, class: select_class_names, describedby: @champ.describedby_id
= render Dsfr::ComboboxComponent.new form: @form, options: @champ.enabled_non_empty_options(other: true), selected: @champ.selected, input_html_options: { name: :value, id: @champ.input_id, class: select_class_names, describedby: @champ.describedby_id }
- else
= @form.select :value,
@champ.enabled_non_empty_options(other: true),

View file

@ -6,10 +6,7 @@
= render Dsfr::ComboboxComponent.new form: f,
url: datasource_endpoint,
selected: format_displayed_value(chorus_configuration_attribute),
id: chorus_configuration_attribute,
class: 'fr-select',
describedby: label_id,
name: :chorus_configuration_attribute do
input_html_options: { id: chorus_configuration_attribute, class: 'fr-select', describedby: label_id, name: :chorus_configuration_attribute } do
= f.hidden_field chorus_configuration_attribute, data: { value_slot: 'data' }, value: format_hidden_value(chorus_configuration_attribute)
= f.submit "Enregister", class: 'fr-btn'

View file

@ -7,10 +7,12 @@ const AUTOSUBMIT_DATE_DEBOUNCE_DELAY = 5000;
const AUTOSUBMIT_EVENTS = ['input', 'change', 'blur'];
export class AutosubmitController extends ApplicationController {
static targets = ['submitter'];
static targets = ['submitter', 'input'];
declare readonly submitterTarget: HTMLButtonElement | HTMLInputElement;
declare readonly hasSubmitterTarget: boolean;
declare readonly inputTarget: HTMLInputElement;
declare readonly hasInputTarget: boolean;
#dateTimeChangedInputs = new WeakSet<HTMLElement>();
@ -66,6 +68,7 @@ export class AutosubmitController extends ApplicationController {
private findTargetElement(event: Event) {
const target = event.target;
if (
!isFormInputElement(target) ||
this.preventAutosubmit(target, event.type)
@ -82,6 +85,9 @@ export class AutosubmitController extends ApplicationController {
if (target.disabled) {
return true;
}
if (this.hasInputTarget && this.inputTarget != target) {
return true;
}
if (
Boolean(target.getAttribute('data-no-autosubmit-on-empty')) &&
target.value == ''

View file

@ -103,10 +103,10 @@ class Dsfr::ComboboxComponentPreview < ViewComponent::Preview
]
def simple_select_with_options
render Dsfr::ComboboxComponent.new(name: :value, options: OPTIONS, selected: OPTIONS.sample, id: 'simple-select', class: 'width-33')
render Dsfr::ComboboxComponent.new(options: OPTIONS, selected: OPTIONS.sample, input_html_options: { name: :value, id: 'simple-select', class: 'width-33' })
end
def simple_select_with_options_and_allows_custom_value
render Dsfr::ComboboxComponent.new(name: :value, options: OPTIONS, selected: OPTIONS.sample, id: 'simple-select', class: 'width-33', allows_custom_value: true)
render Dsfr::ComboboxComponent.new(options: OPTIONS, selected: OPTIONS.sample, allows_custom_value: true, input_html_options: { id: 'simple-select', class: 'width-33', name: :value })
end
end