-# Genera un listado de checkboxes entre los que se puede elegir para guardar :ruby id = "#{base}_#{attribute}" name = "#{base}[#{attribute}][]" form_id = "form-#{Nanoid.generate}" modal_id = "modal-#{Nanoid.generate}" post_form_id = "post-form-#{Nanoid.generate}" %div{ id: modal_id, data: { controller: 'modal array', 'array-original-value': metadata.value.to_json, 'array-new-array-value': site_posts_new_related_post_path(site) } } .form-group = hidden_field_tag name, '' = label_tag id, post_label_t(attribute, post: post) -# Mostramos la lista de valores actuales. Al aceptar el modal, se vacía el listado y se completa en base a renderizaciones con HTMX. Para poder hacer eso, tenemos que poder acceder a todos los items dentro del modal (como array.item) y enviar el valor al endpoint que devuelve uno por uno. Esto lo tenemos disponible en Stimulus, pero queremos usar HTMX o técnica similar para poder renderizar del lado del servidor. Para poder cancelar, mantenemos el estado original y desactivamos o activamos los ítemes según estén incluidos en esa lista o no. .row.row-cols-1.row-cols-md-2{ data: { target: 'array.current' } } - metadata.values.slice(*metadata.value).each do |value| = render 'posts/new_array_value', value: value = render 'bootstrap/btn', content: t('.edit'), action: 'modal#show' = render 'bootstrap/modal', id: id, modal_content_attributes: { class: 'h-100' }, hide_actions: ['array#cancel'] do - content_for :"#{id}_header" do .form-group.flex-grow-1.mb-0 = label_tag id, post_label_t(attribute, post: post) %input.form-control{ data: { target: 'array.search', action: 'input->array#search' }, type: 'search', placeholder: t('.filter') } - content_for :"#{id}_body" do .form-group.mb-0{ id: "#{id}_body" } - metadata.values.each_pair do |value, uuid| .mb-2{ data: { target: 'array.item', 'searchable-value': value.remove_diacritics.downcase, value: uuid } } = render 'bootstrap/custom_checkbox', name: name, id: "value-#{Nanoid.generate}", value: uuid, checked: metadata.value.include?(uuid), content: value -# Según la definición del campo, si hay un filtro, tenemos que poder elegir qué tipo de esquema queremos o si hay uno solo, siempre vamos a enviar ese. Si no hay ninguno, tendríamos que poder elegir entre todos los esquemas. - content_for :"#{id}_footer" do - layout = metadata.filter[:layout] - if layout.is_a?(String) %input{ type: 'hidden', name: 'layout', value: layout, form: post_form_id } = render 'bootstrap/btn', content: t('.add', layout: site.layouts[layout].humanized_name), form: post_form_id, type: 'submit', class: 'm-0 mr-1' - else - layouts = layout&.map { |x| site.layouts[x] } - layouts ||= site.layouts.values .input-group.w-auto.flex-grow-1.my-0 %select.form-control{ form: post_form_id, name: 'layout' } - layouts.each do |layout| %option{ value: layout.name }= layout.humanized_name .input-group-append = render 'bootstrap/btn', content: t('.add', layout: ''), form: post_form_id, type: 'submit', class: 'mb-0 mr-0' = render 'bootstrap/btn', content: t('.accept'), action: 'array#accept modal#hide', class: 'm-0 mr-1' = render 'bootstrap/btn', content: t('.cancel'), action: 'array#cancel modal#hide', class: 'm-0' - content_for :post_form do %form{ id: post_form_id }