diff --git a/app/components/editable_champ/drop_down_list_component/drop_down_list_component.html.haml b/app/components/editable_champ/drop_down_list_component/drop_down_list_component.html.haml index 286a437e0..f2369b33c 100644 --- a/app/components/editable_champ/drop_down_list_component/drop_down_list_component.html.haml +++ b/app/components/editable_champ/drop_down_list_component/drop_down_list_component.html.haml @@ -8,12 +8,12 @@ - if !@champ.mandatory? %label.blank-radio - = @form.radio_button :value, '' + = @form.radio_button :value, '', checked: @champ.value.blank? && !@champ.other? Non renseigné - if @champ.drop_down_other? %label - = @form.radio_button :value, Champs::DropDownListChamp::OTHER, checked: @champ.other_value_present? + = @form.radio_button :value, Champs::DropDownListChamp::OTHER, checked: @champ.other? Autre - else = @form.select :value, @champ.options_without_empty_value_when_mandatory(@champ.options), { selected: @champ.selected }, required: @champ.required?, id: @champ.input_id, aria: { describedby: @champ.describedby_id } diff --git a/app/components/editable_champ/drop_down_other_input_component.rb b/app/components/editable_champ/drop_down_other_input_component.rb index 94e695d4c..bb8f5665e 100644 --- a/app/components/editable_champ/drop_down_other_input_component.rb +++ b/app/components/editable_champ/drop_down_other_input_component.rb @@ -1,2 +1,5 @@ class EditableChamp::DropDownOtherInputComponent < EditableChamp::EditableChampBaseComponent + def render? + @champ.other? + end end diff --git a/app/components/editable_champ/drop_down_other_input_component/drop_down_other_input_component.html.haml b/app/components/editable_champ/drop_down_other_input_component/drop_down_other_input_component.html.haml index 168c008dc..f0160046b 100644 --- a/app/components/editable_champ/drop_down_other_input_component/drop_down_other_input_component.html.haml +++ b/app/components/editable_champ/drop_down_other_input_component/drop_down_other_input_component.html.haml @@ -1,4 +1,4 @@ -.drop_down_other{ class: @champ.other_value_present? ? '' : 'hidden' } +.drop_down_other .notice %label{ for: dom_id(@champ, :value_other) } Veuillez saisir votre autre choix - = @form.text_field :value_other, maxlength: 200, size: nil, id: dom_id(@champ, :value_other), disabled: !@champ.other_value_present? + = @form.text_field :value_other, maxlength: 200, size: nil, id: dom_id(@champ, :value_other) diff --git a/app/components/editable_champ/editable_champ_component.rb b/app/components/editable_champ/editable_champ_component.rb index 622447493..1b1e78132 100644 --- a/app/components/editable_champ/editable_champ_component.rb +++ b/app/components/editable_champ/editable_champ_component.rb @@ -30,11 +30,6 @@ class EditableChamp::EditableChampComponent < ApplicationComponent # This is an editable champ. Lets find what controllers it might need. controllers = ['autosave'] - # This is a dropdown champ. Activate special behaviours it might have. - if @champ.simple_drop_down_list? || @champ.linked_drop_down_list? - controllers << 'champ-dropdown' - end - controllers.join(' ') end end diff --git a/app/javascript/controllers/champ_dropdown_controller.ts b/app/javascript/controllers/champ_dropdown_controller.ts deleted file mode 100644 index c65b7dd95..000000000 --- a/app/javascript/controllers/champ_dropdown_controller.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - isSelectElement, - isCheckboxOrRadioInputElement, - show, - hide -} from '@utils'; - -import { ApplicationController } from './application_controller'; - -export class ChampDropdownController extends ApplicationController { - connect() { - this.on('change', (event) => this.onChange(event)); - } - - private onChange(event: Event) { - const target = event.target as HTMLInputElement; - if (!target.disabled) { - if (isSelectElement(target) || isCheckboxOrRadioInputElement(target)) { - this.toggleOtherInput(target); - } - } - } - - private toggleOtherInput(target: HTMLSelectElement | HTMLInputElement) { - const parent = target.closest('.editable-champ-drop_down_list'); - const inputGroup = parent?.querySelector('.drop_down_other'); - if (inputGroup) { - const input = inputGroup.querySelector('input'); - if (input) { - if (target.value == '__other__') { - show(inputGroup); - input.disabled = false; - input.focus(); - } else { - hide(inputGroup); - input.disabled = true; - } - } - } - } -} diff --git a/app/models/champs/drop_down_list_champ.rb b/app/models/champs/drop_down_list_champ.rb index 23d4a27bf..467643673 100644 --- a/app/models/champs/drop_down_list_champ.rb +++ b/app/models/champs/drop_down_list_champ.rb @@ -21,6 +21,7 @@ # type_de_champ_id :integer # class Champs::DropDownListChamp < Champ + store_accessor :value_json, :other THRESHOLD_NB_OPTIONS_AS_RADIO = 5 OTHER = '__other__' delegate :options_without_empty_value_when_mandatory, to: :type_de_champ @@ -44,7 +45,7 @@ class Champs::DropDownListChamp < Champ end def selected - other_value_present? ? OTHER : value + other? ? OTHER : value end def disabled_options @@ -55,22 +56,28 @@ class Champs::DropDownListChamp < Champ drop_down_list_enabled_non_empty_options end - def other_value_present? - drop_down_other? && value.present? && drop_down_list_options.exclude?(value) + def other? + drop_down_other? && (other || (value.present? && drop_down_list_options.exclude?(value))) end def value=(value) - if value != OTHER + if value == OTHER + self.other = true + write_attribute(:value, nil) + else + self.other = false write_attribute(:value, value) end end def value_other=(value) - write_attribute(:value, value) + if other? + write_attribute(:value, value) + end end def value_other - other_value_present? ? value : "" + other? ? value : "" end def in?(options) diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index b3ec31428..3b00828c5 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -504,7 +504,8 @@ class TypeDeChamp < ApplicationRecord type_champs.fetch(:communes), type_champs.fetch(:multiple_drop_down_list), type_champs.fetch(:dossier_link), - type_champs.fetch(:linked_drop_down_list) + type_champs.fetch(:linked_drop_down_list), + type_champs.fetch(:drop_down_list) true else false diff --git a/spec/components/editable_champ/editable_champ_component_spec.rb b/spec/components/editable_champ/editable_champ_component_spec.rb index 77a6d0645..de9250670 100644 --- a/spec/components/editable_champ/editable_champ_component_spec.rb +++ b/spec/components/editable_champ/editable_champ_component_spec.rb @@ -34,14 +34,14 @@ describe EditableChamp::EditableChampComponent, type: :component do it { expect(subject).to eq(data) } context 'when a public dropdown champ' do - let(:controllers) { ['autosave', 'champ-dropdown'] } + let(:controllers) { ['autosave'] } let(:champ) { create(:champ_drop_down_list, dossier: dossier) } it { expect(subject).to eq(data) } end context 'when a private dropdown champ' do - let(:controllers) { ['autosave', 'champ-dropdown'] } + let(:controllers) { ['autosave'] } let(:champ) { create(:champ_drop_down_list, dossier: dossier, private: true) } it { expect(subject).to eq(data) } @@ -49,14 +49,14 @@ describe EditableChamp::EditableChampComponent, type: :component do end context 'when a public dropdown champ' do - let(:controllers) { ['autosave', 'champ-dropdown'] } + let(:controllers) { ['autosave'] } let(:champ) { create(:champ_drop_down_list, dossier: dossier) } it { expect(subject).to eq(data) } end context 'when a private dropdown champ' do - let(:controllers) { ['autosave', 'champ-dropdown'] } + let(:controllers) { ['autosave'] } let(:champ) { create(:champ_drop_down_list, dossier: dossier, private: true) } it { expect(subject).to eq(data) } diff --git a/spec/system/users/dropdown_spec.rb b/spec/system/users/dropdown_spec.rb index dc5cb0735..e0134bcb2 100644 --- a/spec/system/users/dropdown_spec.rb +++ b/spec/system/users/dropdown_spec.rb @@ -59,7 +59,7 @@ describe 'dropdown list with other option activated', js: true do scenario 'with a select and other, selecting a value save it (avoid hidden other_value to be sent)' do fill_individual - find(".drop_down_other input", visible: false) + expect(page).not_to have_selector(".drop_down_other input") select("Autre") find(".drop_down_other input", visible: true)