JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/startbootstrap-sb-admin-2/3.3.7+1/js/sb-admin-2.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/startbootstrap-sb-admin-2/3.3.7+1/css/sb-admin-2.min.css">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<h1 class="page-header">Categorization</h1>
</div>
<!-- /.col-lg-12 -->
</div>
<div class="row dragging-area">
<div class="col-md-4">
<h4>Drag list items into level 3 folders</h4>
<ul class="list-group" style="font-size:x-small; overflow-y:scroll; height: 75%">
<li id="1" class="list-group-item draggable">1</li>
<li id="2" class="list-group-item draggable">2</li>
<li id="3" class="list-group-item draggable">3</li>
</ul>
</div>
<div class="col-md-4">
<h4>Categories</h4>
<ul class="list-group" id="root" style="overflow-y:scroll; height: 150px">
<li class="list-group-item category-droppable" id="level1">
<span class="glyphicon glyphicon-chevron-right"></span>FirstLvL
<ul class="list-group" id="level1">
<li class="list-group-item category-droppable" id="level2">
<span class="glyphicon glyphicon-chevron-right"></span>SecondLvL
<ul class="list-group" id="level2">
<li class="list-group-item category-droppable" name="A" id="level3">A</li>
<li class="list-group-item category-droppable"...
CSS
.list-group.list-group-root {
padding: 0;
}
.list-group.list-group-root .list-group {
margin-bottom: 0;
}
.list-group.list-group-root .list-group-item {
border-radius: 0;
border-width: 1px 0 0 0;
}
.list-group.list-group-root > .list-group-item:first-child {
border-top-width: 0;
}
.list-group.list-group-root > .list-group > .list-group-item {
padding-left: 30px;
}
.list-group.list-group-root > .list-group > .list-group > .list-group-item {
padding-left: 45px;
}
.list-group-item .glyphicon {
margin-right: 5px;
}
JavaScript
var globalTimer;
var showing = null;
var active = $(document);
var current = null;
$(document).ready(function() {
$('.draggable').draggable({
helper: 'clone',
appendTo: "body",
zIndex: 100,
refreshPositions: true,
revert: 'invalid',
start: function(event, ui) {
$(this).css('visibility', 'hidden');
},
stop: function(event, ui) {
$(this).css('visibility', 'visible');
}
});
$('li.category-droppable').droppable({
tolerance: 'pointer',
out: function(event, ui) {
if ($(this).attr('id') == 'level2') {
$(this).find('ul:first').slideUp();
$(this).find('span.glyphicon:first').toggleClass("glyphicon-chevron-right").toggleClass('glyphicon-chevron-down');
}
},
over: function(event, ui) {
event.stopPropagation();
$(this).find('ul:first').slideDown();
if ($(this).attr('id') == 'level3') {
if (!$(this).is(active)) {
current = $(this);
active.removeClass('list-group-item-info');
current.addClass('list-group-item-info');
globalTimer = setTimeout(function() {
current.addClass('active');
active.removeClass('active');
active = current;
if (showing) {
showing.hide()
}
load_category(current.html(), $('#' + current.attr('name')).find("ul:first"));
$('#' + current.attr('name')).show();
showing = $('#' + current.attr('name'));
}, 500);
}
} else if ($(this).attr('id') == 'level1' || $(this).attr('id') == 'level2') {
$(this).find('span.glyphicon:first').toggleClass("glyphicon-chevron-right").toggleClass('glyphicon-chevron-down');
}
},
drop: function(event, ui) {
...