diff --git a/app/javascript/controllers/required_checkbox_controller.js b/app/javascript/controllers/required_checkbox_controller.js new file mode 100644 index 00000000..9754b506 --- /dev/null +++ b/app/javascript/controllers/required_checkbox_controller.js @@ -0,0 +1,24 @@ +import { Controller } from "stimulus"; + +/* + * Para poder indicar que al menos uno del grupo de checkboxes es + * obligatorio, marcamos uno como `required` (que es el que mostraría el + * error) y se lo quitamos cuando detectamos que alguno cambió. + */ +export default class extends Controller { + static targets = ["required", "checkbox"]; + + connect() { + } + + /* + * El grupo deja de ser obligatorio cuando al menos uno está activo. + */ + change(event = undefined) { + if (event.target.checked) { + this.requiredTarget.required = false; + } else { + this.requiredTarget.required = !Array.from(this.checkboxTargets).some(x => x.checked); + } + } +} diff --git a/app/views/posts/attributes/_new_array.haml b/app/views/posts/attributes/_new_array.haml index d0d659dd..4293ded1 100644 --- a/app/views/posts/attributes/_new_array.haml +++ b/app/views/posts/attributes/_new_array.haml @@ -5,13 +5,19 @@ name = "#{base}[#{attribute}][]" form_id = random_id -%div{ data: { controller: 'modal array enter', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } } +%div{ data: { controller: "modal array enter#{' required-checkbox' if metadata.required}", 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_array_value_path(site) } } %template{ data: { target: 'array.placeholder' } } .col.mb-3{ 'aria-hidden': 'true' } %span.placeholder.w-100 - .form-group - = hidden_field_tag name, '' + .form-group.mb-0 + -# + Si la lista es obligatoria, al menos uno de los ítems tiene que + estar activado. Logramos esto con un checkbox oculto que se marca + como obligatorio al validar el formulario. + - if metadata.required + %input.form-control{ type: 'checkbox', name: name, data: { target: 'required-checkbox.required' }, required: metadata.value.empty? } + .invalid-feedback Requerido! .d-flex.align-items-center.justify-content-between = label_tag id, post_label_t(attribute, post: post) = render 'bootstrap/btn', content: t('.edit'), action: 'modal#show' @@ -41,7 +47,7 @@ -# Eliminamos las tildes para poder buscar independientemente de cómo se escriba - metadata.values.sort_by(&:remove_diacritics).each do |value| .mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: value } } - = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: value, checked: metadata.value.include?(value), content: value + = render 'bootstrap/custom_checkbox', name: name, id: random_id, value: value, checked: metadata.value.include?(value), content: value, data: { action: 'required-checkbox#change', target: 'required-checkbox.checkbox' } - content_for :"#{id}_footer" do .input-group.w-auto.flex-grow-1.my-0