refactor(drop_down_list_champ): other option

This commit is contained in:
Paul Chavard 2021-10-26 20:42:17 +02:00 committed by kara Diaby
parent f1f2b76a3d
commit 8154daf847
5 changed files with 60 additions and 91 deletions

View file

@ -337,8 +337,8 @@ module Users
def champs_params def champs_params
params.permit(dossier: { params.permit(dossier: {
champs_attributes: [ champs_attributes: [
:id, :value, :external_id, :primary_value, :secondary_value, :numero_allocataire, :code_postal, :piece_justificative_file, value: [], :id, :value, :value_other, :external_id, :primary_value, :secondary_value, :numero_allocataire, :code_postal, :piece_justificative_file, value: [],
champs_attributes: [:id, :_destroy, :value, :external_id, :primary_value, :secondary_value, :numero_allocataire, :code_postal, :piece_justificative_file, value: []] champs_attributes: [:id, :_destroy, :value, :value_other, :external_id, :primary_value, :secondary_value, :numero_allocataire, :code_postal, :piece_justificative_file, value: []]
] ]
}) })
end end

View file

@ -21,72 +21,29 @@ delegate('click', '.dropdown-button', (event) => {
} }
}); });
const radios = document.querySelectorAll('input[type="radio"]'); function onChangeSelectWithOther(target) {
const selects = Array.from( const parent = target.closest('.editable-champ-drop_down_list');
document.querySelectorAll('.select_drop_down_other') const inputGroup = parent?.querySelector('.drop_down_other');
); if (inputGroup) {
const radioInputs = Array.from( const input = inputGroup.querySelector('input');
document.querySelectorAll('.text_field_drop_down_other_radio') if (target.value === '__other__') {
); show(inputGroup);
input.disabled = false;
const radioNotices = Array.from(
document.querySelectorAll('.drop_down_other_radio_notice')
);
const selectNotices = Array.from(
document.querySelectorAll('.drop_down_other_select_notice')
);
const selectInputs = Array.from(
document.querySelectorAll('.text_field_drop_down_other_select')
);
const radioButtons = Array.from(
document.querySelectorAll('.radio_button_drop_down_other')
);
const radioButtonsObject = radioButtons.map((radioButton, index) => {
return {
radioButton: radioButton,
input: radioInputs[index],
notice: radioNotices[index],
key: radioButton.getAttribute('name')
};
});
const selectObject = selects.map((select, index) => {
return {
select: select,
input: selectInputs[index],
notice: selectNotices[index],
key: select.getAttribute('name')
};
});
for (const el of selectObject) {
selects.forEach((select) => {
select.addEventListener('change', () => {
if (el.select.value === 'Autre') {
el.notice.style.display = 'block';
el.input.setAttribute('name', el.key);
} else { } else {
el.notice.style.display = 'none'; hide(inputGroup);
el.input.setAttribute('name', ''); input.disabled = true;
}
} }
});
});
} }
for (const el of radioButtonsObject) { delegate('change', '.editable-champ-drop_down_list select', (event) => {
radios.forEach((radio) => { onChangeSelectWithOther(event.target);
radio.addEventListener('click', () => {
if (el.radioButton.checked) {
el.notice.style.display = 'block';
el.input.setAttribute('name', el.key);
} else {
el.notice.style.display = 'none';
el.input.setAttribute('name', '');
}
});
}); });
delegate(
'click',
'.editable-champ-drop_down_list input[type="radio"]',
(event) => {
onChangeSelectWithOther(event.target);
} }
);

View file

@ -21,6 +21,7 @@
# #
class Champs::DropDownListChamp < Champ class Champs::DropDownListChamp < Champ
THRESHOLD_NB_OPTIONS_AS_RADIO = 5 THRESHOLD_NB_OPTIONS_AS_RADIO = 5
OTHER = '__other__'
def render_as_radios? def render_as_radios?
enabled_non_empty_options.size <= THRESHOLD_NB_OPTIONS_AS_RADIO enabled_non_empty_options.size <= THRESHOLD_NB_OPTIONS_AS_RADIO
@ -31,8 +32,16 @@ class Champs::DropDownListChamp < Champ
end end
def options def options
if drop_down_other?
drop_down_list_options + [["Autre", OTHER]]
else
drop_down_list_options drop_down_list_options
end end
end
def selected
other_value_present? ? OTHER : value
end
def disabled_options def disabled_options
drop_down_list_disabled_options drop_down_list_disabled_options
@ -43,10 +52,24 @@ class Champs::DropDownListChamp < Champ
end end
def other_value_present? def other_value_present?
self.value.present? && self.options.exclude?(self.value) value.present? && drop_down_list_options.exclude?(value)
end end
def drop_down_other? def drop_down_other?
drop_down_other drop_down_other
end end
def value=(value)
if value != OTHER
write_attribute(:value, value)
end
end
def value_other=(value)
write_attribute(:value, value)
end
def value_other
other_value_present? ? value : ""
end
end end

View file

@ -1,5 +1,4 @@
%input{ type: "text", .drop_down_other{ class: champ.other_value_present? ? '' : 'hidden' }
value: champ.other_value_present? ? champ.value : "", .notice
class: class_name, %p Veuillez saisir votre autre choix
maxlength: "200", = form.text_field :value_other, { maxlength: "200", placeholder: "Saisissez ici", disabled: !champ.other_value_present? }
placeholder: "Saisissez ici" }

View file

@ -10,23 +10,13 @@
%label.blank-radio %label.blank-radio
= form.radio_button :value, '' = form.radio_button :value, ''
Non renseigné Non renseigné
- if champ.drop_down_other? - if champ.drop_down_other?
%label %label
= form.radio_button :value, '', class: "radio_button_drop_down_other", id: "radio_button_drop_down_other_#{champ.id}", checked: champ.other_value_present? = form.radio_button :value, Champs::DropDownListChamp::OTHER, checked: champ.other_value_present?
Autre Autre
- if champ.drop_down_other?
.notice.drop_down_other_radio_notice{ style: "#{champ.other_value_present? ? "display:block" : "display:none"}" }
%p Veuillez saisir votre autre choix
= render partial: "shared/dossiers/drop_down_other_input", locals: { champ: champ, class_name: "text_field_drop_down_other_radio" }
- else - else
= form.select :value, = form.select :value, champ.options, { selected: champ.selected, required: champ.mandatory? }
champ.drop_down_other? ? champ.options.concat(["Autre"]) : champ.options,
{ selected: champ.other_value_present? ? "Autre" : champ.value,
required: champ.mandatory? },
{ class: champ.drop_down_other? ? "select_drop_down_other" : ""}
- if champ.drop_down_other? - if champ.drop_down_other?
.notice.drop_down_other_select_notice{ style: "#{champ.other_value_present? ? "display:block" : "display:none"}" } = render partial: "shared/dossiers/drop_down_other_input", locals: { form: form, champ: champ }
= render partial: "shared/dossiers/drop_down_other_input", locals: { champ: champ, class_name: "text_field_drop_down_other_select" }