I'm new to using SortableJS, so I'm not sure if this is by design or if I'm doing it wrong.
I can drag elements to be children of elements that already have at least one child element, but I cannot drag them into elements that don't have any children. And if I drag all the elements out of an element so that it has none, I cannot drag them back into that element again.
Here's my code; I can drag anything to be a child of Home
, PHP Support
, or PHP 7 Support
. Nothing else will accept a child element.
$(document).ready(function() {
document.querySelectorAll("#category-list ul").forEach(function(listEl) {
new Sortable(listEl, {
group: "nested",
handle: ".handle",
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
onEnd: function(evt) {
var order = [];
$("#category-list li").each(function(index, element) {
order.push({
id: $(element).data("id"),
parent_id: $(element).closest("ul").closest("li").data("id") || null,
position: index
});
});
}
});
});
});
@import "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css";
@import "https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/fontawesome.min.css";
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/js/all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.2/Sortable.min.js"></script>
<div class="container" id="handle">
<ul class="list-group" id="category-list">
<li class="list-group-item" data-id="17"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Home<ul>
<ul class="list-group" id="category-list">
<li class="list-group-item" data-id="15"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Test Forum</li>
<li class="list-group-item" data-id="9"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Hosting Support</li>
<li class="list-group-item" data-id="21"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Forum</li>
<li class="list-group-item" data-id="10"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP Support<ul>
<ul class="list-group" id="category-list">
<li class="list-group-item" data-id="18"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP 7 Support<ul>
<ul class="list-group" id="category-list">
<li class="list-group-item" data-id="20"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>HTAccess</li>
</ul>
</ul>
</li>
<li class="list-group-item" data-id="11"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP 8 Support</li>
<li class="list-group-item" data-id="19"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>MySQL Support</li>
</ul>
</ul>
</li>
</ul>
</ul>
</li>
</ul>
</div>
I was able to solve the issue by adjusting my code a bit. This script ensures that all list items, even those without children, have a nested ul
element initialized. This way, I can drag elements to any list item, regardless of whether it initially has children.
function initializeSortable(el) {
new Sortable(el, {
group: 'nested',
animation: 150,
handle: ".handle",
fallbackOnBody: true,
swapThreshold: 0.65,
onEnd: function (evt) {
var order = [];
$('#category-list li').each(function (index, element) {
order.push({
id: $(element).data('id'),
parent_id: $(element).closest('ul').closest('li').data('id') || null,
position: index
});
});
}
});
}
document.querySelectorAll('#category-list ul').forEach(function (listEl) {
initializeSortable(listEl);
});
document.querySelectorAll('#category-list li').forEach(function (listItem) {
if (!listItem.querySelector('ul')) {
var newUl = document.createElement('ul');
newUl.classList.add('list-group');
listItem.appendChild(newUl);
initializeSortable(newUl);
}
});
@import "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css";
@import "https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/fontawesome.min.css";
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/js/all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.2/Sortable.min.js"></script>
<ul class="list-group" id="category-list">
<li class="list-group-item" data-id="17"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Home
<ul class="list-group">
<li class="list-group-item" data-id="15"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Test Forum</li>
<li class="list-group-item" data-id="21"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Forum</li>
<li class="list-group-item" data-id="10"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP Support
<ul class="list-group">
<li class="list-group-item" data-id="11"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP 8 Support</li>
<li class="list-group-item" data-id="18"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>PHP 7 Support
<ul class="list-group">
<li class="list-group-item" data-id="20"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>HTAccess</li>
<li class="list-group-item" data-id="19"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>MySQL Support</li>
</ul>
</li>
</ul>
</li>
<li class="list-group-item" data-id="9"><i class="fa-solid fa-up-down-left-right handle pe-2"></i>Hosting Support</li>
</ul>
</li>
</ul>