I'm working on a drag and drop page with multiple lists on the page but have several issues getting it right. Issues as follows. 1/ I'm unable to drop an item into an empty list and 2/ I'm unable to add an item to the end of a list that does have items in it. Here's my current code:
<div class="flex">
<ul id="todo-1" class="container flex-auto p-4 mx-4 border-2 droppable" style="min-height: 300px;">
<li draggable="true" class="m-2 cursor-pointer box">item 1/1</li>
<li draggable="true" class="m-2 cursor-pointer box">item 1/2</li>
<li draggable="true" class="m-2 cursor-pointer box">item 1/3</li>
</ul>
<ul id="todo-2" class="container flex-auto p-4 mx-4 border-2 droppable">
<li draggable="true" class="m-2 cursor-pointer box">item 2/1</li>
<li draggable="true" class="m-2 cursor-pointer box">item 2/2</li>
<li draggable="true" class="m-2 cursor-pointer box">item 2/3</li>
</ul>
<ul id="todo-3" class="container flex-auto p-4 mx-4 border-2 droppable">
<li draggable="true" class="m-2 cursor-pointer box">item 3/1</li>
<li draggable="true" class="m-2 cursor-pointer box">item 3/2</li>
<li draggable="true" class="m-2 cursor-pointer box">item 3/3</li>
</ul>
<p>alloc</p>
<ul id="alloc-1" class="container flex-auto p-4 mx-24 border-2">
<li draggable="true" class="m-2 cursor-pointer box">item 4/1</li>
<li draggable="true" class="m-2 cursor-pointer box">item 4/2</li>
<li draggable="true" class="m-2 cursor-pointer box">item 4/3</li>
</ul>
</div>
<div class="flex">
<ul id="done-1" class="container flex-auto p-4 mx-4 border-2 droppable" style="min-height: 300px;">
<li draggable="true" class="m-2 cursor-pointer box">item 5/1</li>
<li draggable="true" class="m-2 cursor-pointer box">item 5/2</li>
<li draggable="true" class="m-2 cursor-pointer box">item 5/3</li>
</ul>
<ul id="done-2" class="container flex-auto p-4 mx-4 border-2 droppable">
</ul>
<ul id="done-3" class="container flex-auto p-4 mx-4 border-2 droppable">
<li draggable="true" class="m-2 cursor-pointer box">item 7/1</li>
<li draggable="true" class="m-2 cursor-pointer box">item 7/2</li>
<li draggable="true" class="m-2 cursor-pointer box">item 7/3</li>
</ul>
<p>alloc</p>
<ul id="alloc-2" class="container flex-auto p-4 mx-24 border-2 droppable">
</ul>
</div>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
let dragSrcEl = null;
let placeholder = null;
function handleDragStart(e) {
this.style.opacity = '0.4';
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.outerHTML);
// Create a placeholder element
placeholder = document.createElement('li');
placeholder.className = 'm-2 cursor-pointer box placeholder';
placeholder.style.height = this.offsetHeight + 'px'; // Match the height
}
function handleDragEnd(e) {
this.style.opacity = '1';
if (placeholder && placeholder.parentNode) {
placeholder.parentNode.removeChild(placeholder);
}
items.forEach(function (item) {
item.classList.remove('over');
});
}
function handleDragOver(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'move';
}
function handleDragEnter(e) {
this.classList.add('over');
if (placeholder) {
if (this.classList.contains('box')) {
this.parentNode.insertBefore(placeholder, this);
} else if (this.nodeName === 'UL') {
this.appendChild(placeholder);
}
}
}
function handleDragLeave(e) {
this.classList.remove('over');
}
function handleDrop(e) {
e.stopPropagation();
if (dragSrcEl !== this) {
if (placeholder && placeholder.parentNode) {
placeholder.parentNode.removeChild(placeholder);
}
if (e.target.classList.contains('box')) {
this.parentNode.insertBefore(dragSrcEl, this);
} else if (e.target.nodeName === 'UL' || e.target.classList.contains('droppable')) {
e.target.appendChild(dragSrcEl);
}
}
}
let items = document.querySelectorAll('.container .box');
items.forEach(function (item) {
item.addEventListener('dragstart', handleDragStart);
item.addEventListener('dragover', handleDragOver);
item.addEventListener('dragenter', handleDragEnter);
item.addEventListener('dragleave', handleDragLeave);
item.addEventListener('dragend', handleDragEnd);
item.addEventListener('drop', handleDrop);
});
});
</script>
I have other things to do on this but getting this aspect to work will help me progress.