feat(dossier): use turbo on select with other

This commit is contained in:
Paul Chavard 2023-03-30 00:24:11 +02:00
parent eb599394e0
commit 0912a30eb0
9 changed files with 27 additions and 62 deletions

View file

@ -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 }

View file

@ -1,2 +1,5 @@
class EditableChamp::DropDownOtherInputComponent < EditableChamp::EditableChampBaseComponent
def render?
@champ.other?
end
end

View file

@ -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)

View file

@ -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

View file

@ -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<HTMLElement>('.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;
}
}
}
}
}

View file

@ -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)

View file

@ -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

View file

@ -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) }

View file

@ -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)