I have a relatively simple web app that I'm creating as a bookshelf and I want the user to be able to drag and drop books between the bookshelves. It works exactly as I want when I drop a book to the "right" side of the existing books in one of the bookshelves. The book that has been dragged and dropped is added to the shelf.
Where it isn't working is when I drop a book on top of an existing book. When I do that, the book is removed from the existing shelf -- but it disappears totally instead of being added to the targeted bookshelf as I desire. Its unclear to me why this is.
See here: https://mainstringargs.github.io/bookshelf-data/test.html
(I'm using Firefox, if that is relevant)
Relevant source code is here (raw html): https://github.com/mainstringargs/bookshelf-data/blob/master/test.html
Note: This was originally generated via jekyll in github, but since this problem is not jekyll centric, I'm not including that source code detail.
I largely followed this guide for how to implement drag and drop:
https://www.w3schools.com/html/html5_draganddrop.asp
The relevant javascript code is below. The 'drop' function is intended to drop the relevant list item to the new list.
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data).parentNode);
}
</script>
Each bookshelf is itself wrapped in a div containing a single unordered list (ul) with list items (li) representing each book. Here is a snippet from the first bookshelf:
<div ondrop="drop(event)" ondragover="allowDrop(event)" class="shelf read">
<ul class="books clearfix">
<li id="The_Clean_Coder" class="book">
<img id="img_The_Clean_Coder" draggable="true" ondragstart="drag(event)" class="front" src="/bookshelf-data/assets/img/the_clean_coder.jpg" alt="The Clean Coder">
<div class="back" onclick="" id="read_The_Clean_Coder">
<div class="p0">
<span class="score"><span id="rating_The_Clean_Coder"></span></span>
<script>
var span = document.getElementById("rating_The_Clean_Coder");
var rating = 4.3;
var starWidth = (span.offsetWidth - paddingLeft - (5*gapSize))/5.0;
var gaps = Math.floor(rating);
var width = (rating * starWidth) + (gaps * gapSize);
span.style.width = `${width}px`;
span.title=4.3 +" out of 5";
</script>
<dl class="p10">
<dt>Title:</dt>
<dd>The Clean Coder</dd>
<dt>Author:</dt>
<dd>Robert C. Martin</dd>
<dt>Released:</dt>
<dd>May 23, 2011</dd>
</dl>
<p class="description">
Programmers who endure and succeed amidst swirling uncertainty and nonstop pressure share a common attribute - They care deeply about...
</p>
<a href="https://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073/ref=as_li_ss_tl?crid=9YJ9X71LWCXD&keywords=clean+architecture&qid=1564690296&s=gateway&sprefix=clean+arh,aps,155&sr=8-4&linkCode=ll1&tag=mainstringarg-20&linkId=cd98bbe94682a01daca2dcb8852cf52e&language=en_US" target="_blank">Amazon Link</a>
</div>
</div>
</li>
As you can see, I've added these calls to the bookshelf div: ondrop="drop(event)" ondragover="allowDrop(event)" and on each image, I've included draggable="true" ondragstart="drag(event)". This follows the pattern from the w3schools link, but there are cases where it does not seem to append the item to the unordered list.