// Gallery uploader nativo (drag&drop + click) que ACUMULA archivos. // No depende de Dropzone. Usado por create y edit. document.addEventListener('DOMContentLoaded', function () { var dzEl = document.getElementById('gallery_dropzone'); var hidden = document.getElementById('gallery_images_input'); var preview = document.getElementById('gallery_selected_preview'); var form = document.getElementById('{{ $formId }}'); if (!dzEl || !hidden || !preview) return; var toDelInput = document.getElementById('gallery_images_to_delete'); // solo en edit var existingWrap = document.getElementById('gallery_existing'); // solo en edit var MAX = 12; var MAX_SIZE = 4 * 1024 * 1024; var ACCEPT = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp']; var files = []; var toDelete = []; var existingCount = existingWrap ? existingWrap.querySelectorAll('.gallery-existing-item').length : 0; function slotsLeft() { return MAX - existingCount - files.length; } function syncInput() { var dt = new DataTransfer(); files.forEach(function (f) { if (f instanceof File) dt.items.add(f); }); hidden.files = dt.files; } function render() { preview.innerHTML = ''; files.forEach(function (file, index) { var url = URL.createObjectURL(file); var col = document.createElement('div'); col.className = 'col-6 col-md-3'; col.innerHTML = '
' + '' + '
' + file.name + '
' + '' + '
'; preview.appendChild(col); }); } function addFiles(fileList) { var arr = Array.prototype.slice.call(fileList || []); for (var i = 0; i < arr.length; i++) { var f = arr[i]; if (ACCEPT.indexOf(f.type) === -1) continue; if (f.size > MAX_SIZE) { alert('{{ __('La imagen supera 4MB:') }} ' + f.name); continue; } if (slotsLeft() <= 0) { alert('{{ __('Máximo 12 imágenes en la galería.') }}'); break; } var dup = files.some(function (x) { return x.name === f.name && x.size === f.size && x.lastModified === f.lastModified; }); if (!dup) files.push(f); } syncInput(); render(); } // Click → abrir selector dzEl.addEventListener('click', function () { hidden.click(); }); hidden.addEventListener('change', function () { addFiles(hidden.files); }); // Drag & drop ['dragenter', 'dragover'].forEach(function (ev) { dzEl.addEventListener(ev, function (e) { e.preventDefault(); e.stopPropagation(); dzEl.classList.add('dragover'); }); }); ['dragleave', 'dragend'].forEach(function (ev) { dzEl.addEventListener(ev, function (e) { e.preventDefault(); e.stopPropagation(); dzEl.classList.remove('dragover'); }); }); dzEl.addEventListener('drop', function (e) { e.preventDefault(); e.stopPropagation(); dzEl.classList.remove('dragover'); if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length) addFiles(e.dataTransfer.files); }); // Quitar imagen nueva (preview) preview.addEventListener('click', function (e) { var b = e.target.closest('[data-remove-index]'); if (!b) return; var i = Number(b.getAttribute('data-remove-index')); if (Number.isNaN(i)) return; files.splice(i, 1); syncInput(); render(); }); // Quitar imagen existente (solo edit) if (existingWrap) { existingWrap.addEventListener('click', function (e) { var b = e.target.closest('.remove-existing-gallery-image'); if (!b) return; var id = b.getAttribute('data-image-id'); if (id && toDelete.indexOf(id) === -1) toDelete.push(id); if (toDelInput) toDelInput.value = JSON.stringify(toDelete); var item = b.closest('.gallery-existing-item'); if (item) item.remove(); existingCount = Math.max(0, existingCount - 1); }); } if (form) form.addEventListener('submit', syncInput); });