Drag Drop Nested Lists
by Muthuraman B
HTML
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<div class="drag">
<div class="above">
<p>Col 1</p>
</div>
<div class="drop">
<div class="drag">
<div class="above">
<p>Col 2</p>
</div>
<div class="drop">
<div class="drag">
<div class="above">
<p>Col 3</p>
</div>
<div class="drop">
</div>
</div>
</div>
<div class="below">
<p>Col 2</p>
</div>
</div>
</div>
<div class="below">
<p>Col 1</p>
</div>
</div>
CSS
* {
box-sizing: border-box;
margin: 0;
padding: 0;
position: relative;
font-family: sans-serif;
}
.drag {
border: 1px solid lightblue;
border-right: none;
margin-bottom: 15px;
}
.drag .drop {
margin-left: 15px;
}
.above, .below {
margin: 15px;
}
.marker {
border: 1px dashed lightblue;
}
JavaScript
var dragZones = $(".drag");
dragZones.on('click', function(event) {
var mouseY = event.pageY;
var targetZone;
var targetDist = Infinity;
dragZones.each(function(index) {
// Calculate Distances
var zone = {};
zone.el = $(this);
zone.offset = zone.el.offset();
zone.top = zone.offset.top;
zone.bottom = zone.top + zone.el.outerHeight();
zone.distTop = Math.abs(mouseY - zone.top);
zone.distBottom = Math.abs(mouseY - zone.bottom);
// Use Top Corner
if(zone.distTop < targetDist)
{
targetZone = zone;
targetDist = zone.distTop;
}
// Use Bottom Corner
if (zone.distBottom < targetDist)
{
targetZone = zone;
targetDist = zone.distBottom;
}
});
// Reset Marker
$('.marker').remove();
var marker =
`<div class="drag marker">
<div class="above">
<p>Col 4</p>
</div>
<div class="drop">
</div>
</div>`;
// Inside Closest Element
if (mouseY >= targetZone.top && mouseY <= targetZone.bottom)
{
// Closest to Top Corner
if (targetZone.distTop < targetZone.distBottom)
{
$(marker).prependTo(targetZone.el.children('.drop').first());
}
// Closest to Bottom Corner
else
{
$(marker).appendTo(targetZone.el.children('.drop').first());
}
}
// Outside Closest Element
else
{
// Closest to Top Corner
if (targetZone.distTop < targetZone.distBottom)
{
$(marker).insertBefore(targetZone.el);
}
// Closest to Bottom Corner
else
{
$(marker).insertAfter(targetZone.el);
}
}
event.stopPropagation();
});