(function() { const list = document.getElementById('links-sortable'); if (!list) return; let dragged = null; list.querySelectorAll('li').forEach(li => { li.setAttribute('draggable', true); li.addEventListener('dragstart', () => { dragged = li; li.style.opacity = '.4'; }); li.addEventListener('dragend', () => { dragged = null; li.style.opacity = ''; saveOrder(); }); li.addEventListener('dragover', e => { e.preventDefault(); const after = getDragAfter(list, e.clientY); after ? list.insertBefore(dragged, after) : list.appendChild(dragged); }); }); function getDragAfter(container, y) { return [...container.querySelectorAll('li:not([style*="opacity"])')].reduce((closest, el) => { const box = el.getBoundingClientRect(); const offset = y - box.top - box.height / 2; return offset < 0 && offset > closest.offset ? { offset, element: el } : closest; }, { offset: Number.NEGATIVE_INFINITY }).element; } function saveOrder() { const form = document.getElementById('reorder-form'); if (!form) return; form.querySelectorAll('input').forEach(i => i.remove()); list.querySelectorAll('li[data-id]').forEach(li => { const inp = document.createElement('input'); inp.type = 'hidden'; inp.name = 'order[]'; inp.value = li.dataset.id; form.appendChild(inp); }); form.submit(); } })();