import { Controller } from "@hotwired/stimulus"; import Sortable from "sortablejs"; export default class extends Controller { static targets = [ "container", "input", "preview", "list", "card", "checkbox", "checkIcon", "count", ]; sortable = null; // ------------------------------------------------------------ // Sélection normale // ------------------------------------------------------------ cardClick(event) { const card = event.currentTarget; const checkbox = card.querySelector("input[type='checkbox']"); checkbox.checked = !checkbox.checked; this.updateCard(card, checkbox.checked); this.updateCount(); } toggleCheckbox(event) { const checkbox = event.currentTarget; const card = checkbox.closest("label"); this.updateCard(card, checkbox.checked); this.updateCount(); } updateCard(card, checked) { const icon = card.querySelector( "[data-news--image-selector-target='checkIcon']", ); const overlay = card.querySelector( "[data-news--image-selector-target='overlay']", ); icon.classList.toggle("hidden", !checked); overlay.classList.toggle("hidden", !checked); card.classList.toggle("ring-4", checked); card.classList.toggle("ring-amber-500", checked); } updateCount() { const total = this.checkboxTargets.filter((c) => c.checked).length; if (this.hasCountTarget) { this.countTarget.textContent = `${total} sélectionnée(s)`; } } // ------------------------------------------------------------ // Validation → création du preview + activation du drag&drop // ------------------------------------------------------------ validate() { const selected = this.checkboxTargets .filter((c) => c.checked) .map((c) => c.value); // 🔥 RESET TOTAL DU PREVIEW this.previewTarget.innerHTML = ""; // 🔁 RECONSTRUCTION À PARTIR DE LA SOURCE DE VÉRITÉ selected.forEach((id) => { const card = this.cardTargets.find((c) => c.dataset.id === id); if (!card) return; const img = document.createElement("img"); img.src = card.dataset.url; img.dataset.id = id; img.className = "w-20 h-20 rounded object-cover cursor-move"; this.previewTarget.appendChild(img); }); this.enableSortable(); this.updateOrder(); // ferme la modale document.querySelector("[command='close'][commandfor='dialog']").click(); } // ------------------------------------------------------------ // SortableJS (drag & drop) // ------------------------------------------------------------ enableSortable() { if (this.sortable) { this.sortable.destroy(); // reset si déjà actif } this.sortable = Sortable.create(this.previewTarget, { animation: 150, ghostClass: "opacity-40", onSort: () => { this.updateOrder(); }, }); } updateOrder() { // Supprime les anciennes valeurs const container = this.previewTarget.closest("form"); container .querySelectorAll('input[name="selectedImages[]"]') .forEach((i) => i.remove()); // Crée un input caché par image dans l'ordre Array.from(this.previewTarget.children).forEach((img) => { const hidden = document.createElement("input"); hidden.type = "hidden"; hidden.name = "selectedImages[]"; hidden.value = img.dataset.id; container.appendChild(hidden); }); } }