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
params.permit(dossier: {
champs_attributes: [
:id, :value, :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: []]
:id, :value, :value_other, :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

View file

@ -21,72 +21,29 @@ delegate('click', '.dropdown-button', (event) => {
}
});
const radios = document.querySelectorAll('input[type="radio"]');
const selects = Array.from(
document.querySelectorAll('.select_drop_down_other')
);
const radioInputs = Array.from(
document.querySelectorAll('.text_field_drop_down_other_radio')
);
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 {
el.notice.style.display = 'none';
el.input.setAttribute('name', '');
}
});
});
function onChangeSelectWithOther(target) {
const parent = target.closest('.editable-champ-drop_down_list');
const inputGroup = parent?.querySelector('.drop_down_other');
if (inputGroup) {
const input = inputGroup.querySelector('input');
if (target.value === '__other__') {
show(inputGroup);
input.disabled = false;
} else {
hide(inputGroup);
input.disabled = true;
}
}
}
for (const el of radioButtonsObject) {
radios.forEach((radio) => {
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('change', '.editable-champ-drop_down_list select', (event) => {
onChangeSelectWithOther(event.target);
});
delegate(
'click',
'.editable-champ-drop_down_list input[type="radio"]',
(event) => {
onChangeSelectWithOther(event.target);
}
);

View file

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

View file

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

View file

@ -10,23 +10,13 @@
%label.blank-radio
= form.radio_button :value, ''
Non renseigné
- if champ.drop_down_other?
%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
- 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
= form.select :value,
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" : ""}
= form.select :value, champ.options, { selected: champ.selected, required: champ.mandatory? }
- 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: { champ: champ, class_name: "text_field_drop_down_other_select" }
- if champ.drop_down_other?
= render partial: "shared/dossiers/drop_down_other_input", locals: { form: form, champ: champ }