JSFiddle - React, Tailwind, and code Playground
by Ben Schnell
HTML
<div id="dropzone">
<div id="record-id-1" class="node" draggable="true">One</div>
<div id="record-id-2" class="node" draggable="true">Two</div>
<div id="record-id-3" class="node" draggable="true">Three</div>
<div id="record-id-4" class="node" draggable="true">Four</div>
<div id="record-id-5" class="node" draggable="true">Five</div>
<div id="record-id-6" class="node" draggable="true">Six</div>
<div id="record-id-7" class="node" draggable="true">Seven</div>
<div id="record-id-8" class="node" draggable="true">Eight</div>
</div>
CSS
#dropzone {
background-color: powderblue;
margin: 0.5em;
padding: 0.4em;
min-height: 100vh;
font-size: 1.4em;
}
.node {
background-color: cornsilk;
margin: 0.5em;
padding: 0.4em;
border: 3px skyblue solid;
}
JavaScript
var dropzone = document.getElementById('dropzone');
var nodes = document.getElementsByClassName('node');
var selectedNode = '';
var selectedNodePos = 0;
for (var i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('mousedown', (e) => {
for (var i = 0; i < nodes.length; i++) {
nodes[i].style.backgroundColor = 'cornsilk';
}
document.getElementById(e.target.id).style.backgroundColor = 'tomato';
document.getElementById(e.target.id).style.transition = '0s';
})
nodes[i].addEventListener('dragstart', (e) => {
e.dataTransfer.setData('text', e.target.id);
selectedNode = document.getElementById(e.target.id);
setTimeout(() => {
dropzone.removeChild(selectedNode);
}, 0)
})
}
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
whereAmI(e.clientY);
})
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.insertBefore(selectedNode, dropzone.children[selectedNodePos]);
resetNodes();
setTimeout(() => {
selectedNode.style.backgroundColor = 'cornsilk';
selectedNode.style.transition = '2s';
}, 200);
})
function establishNodePositions() {
for (var i = 0; i < nodes.length; i++) {
var element = document.getElementById(nodes[i]['id']);
var position = element.getBoundingClientRect();
var yTop = position.top;
var yBottom = position.bottom;
nodes[i]['yPos'] = yTop + ((yBottom - yTop)/2);
}
}
function resetNodes() {
for (var i = 0; i < nodes.length; i++) {
document.getElementById(nodes[i]['id']).style.marginTop = '0.5em';
}
}
function whereAmI(currentYPos) {
establishNodePositions();
for (var i = 0; i < nodes.length; i++) {
if (nodes[i]['yPos']<currentYPos) {
var nodeAbove = document.getElementById(nodes[i]['id']);
selectedNodePos = i +1;
} else {
if (!nodeBelow) {
var nodeBelow = document.getElementById(nodes[i]['id']);
}
}
}
if (typeof nodeAbove == 'undefined') {
selectedNodePos = 0;
}
...