Reputation: 4128
I am trying to connect a fancytree and a JQueryUI sortable in a specific manner, such that the following is possible:
The code I have does all of this right now, with one problem which I am having problems ironing out; when I drag a sortable node to the fancytree, it does not retain its position in the sortable; it moves to the end.
What I am looking for is this: exactly the behavior displayed in this sample code, but when dragging from the sortable to the fancytree, the sortable item retains its place.
Here is a fiddle with my code:
And here is the code itself (identical to the fiddle, maybe save someone a click...):
<html>
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script
src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/skin-win8/ui.fancytree.min.css" rel="stylesheet">
<!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.fancytree-all-deps.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.fancytree-all.min.js"></script>
</head>
<body>
<div id="tree"></div>
<ul id="mylist">
<li class="ui-state-default tonga">Item 1</li>
<li class="ui-state-default tonga">Item 2</li>
<li class="ui-state-default tonga">Item 3</li>
<li class="ui-state-default tonga">Item 4</li>
<li class="ui-state-default tonga">Item 5</li>
<li class="ui-state-default tonga">Item 6</li>
<li class="ui-state-default tonga">Item 7</li>
</ul>
<script type="text/javascript">
$(function(){ // on page load
$("#tree").fancytree({
debugLevel: 0,
selectMode: 1,
extensions: ["dnd"],
source: [
{title: "Node 1", key: "1", "baloney": 44},
{title: "Folder 2", key: "2", folder: true, children: [
{title: "Node 2.1", key: "3", myOwnAttr: "abc"},
{title: "Node 2.2", key: "4"}
]}
],
dnd: {
dragStart: function(node, data) {
return true;
},
dragEnter: function(node, data) {
return true;
},
dragDrop: function(node, data) {
if ( !data.otherNode ) {
// it's a draggable from outside the fancytree
node.addNode({title: "Hello butt"}, data.hitMode);
return;
} else {
// SOLUTION: this line enables reorder inside tree
data.otherNode.moveTo(node, data.hitMode);
}
},
initHelper: function(sourceNode, data) {
var helper = data.ui.helper;
var foo = $(helper).find(".fancytree-title")[0].innerHTML;
$(helper).find(".fancytree-drag-helper-img").remove();
$(helper).find(".fancytree-title").replaceWith('<li class="ui-state-default tonga">'+foo+"</li>");
},
updateHelper: function(sourceNode, data) {
},
draggable: {
appendTo: "body",
connectToSortable: "#mylist",
revert: "invalid",
containment: "document"
}
},
});
$("#mylist").sortable(
{
connectWith: "#mylist",
//containment: "parent"
}
).disableSelection();
$(".tonga").draggable({
revert: true,
helper: "clone",
connectToFancytree: true
});
$(".tonga").draggable({
revert: false,
helper: "original",
connectToSortable: "#mylist"
});
});
</script>
</body>
</html>
Upvotes: -1
Views: 501
Reputation: 3067
I think I've figured it out. A few things need to be reworked.
First, the out
event of the sortable object needs to be handled to store whether the item has been drug out of the bounds of the sortable, which is what for some reason reorders the list:
$("#mylist").sortable({
connectWith: "#mylist",
out: function(event, ui) {
// store the original index of the sortable item only if we are moving the mouse (extra events fire which mess this up)
if (event.originalEvent.type === "mousemove") {
$(ui.item).data('drugout', true);
}
}
}).disableSelection();
Then a few event listeners need to be added to the draggable. The start
handler stores the original index of the draggable item. The stop
handler determines if the item has been drug outside the bounds of the sortable. If the item has been drug out of the sortable, then it reinserts the item at it's previous index, effectively preserving the order of the list:
$(".tonga").draggable({
revert: true,
helper: "clone",
connectToFancytree: true,
start: function(event, ui) {
$(event.target).data('previndex', $(event.target).index());
},
stop: function(event, ui) {
if ($(event.target).data('drugout')) {
var originalIndex = $(event.target).data('previndex');
$("#mylist li:last").insertBefore($("#mylist li:eq(" + originalIndex + ")"));
}
}
});
This JSFiddle has a working example.
$(function() { // on page load
$("#tree").fancytree({
debugLevel: 0,
selectMode: 1,
extensions: ["dnd"],
source: [{
title: "Node 1",
key: "1",
"baloney": 44
},
{
title: "Folder 2",
key: "2",
folder: true,
children: [{
title: "Node 2.1",
key: "3",
myOwnAttr: "abc"
},
{
title: "Node 2.2",
key: "4"
}
]
}
],
dnd: {
dragStart: function(node, data) {
return true;
},
dragEnter: function(node, data) {
return true;
},
dragDrop: function(node, data) {
if (!data.otherNode) {
// it's a draggable from outside the fancytree
node.addNode({
title: "Hello butt"
}, data.hitMode);
return;
} else {
// SOLUTION: this line enables reorder inside tree
data.otherNode.moveTo(node, data.hitMode);
}
},
initHelper: function(sourceNode, data) {
var helper = data.ui.helper;
var foo = $(helper).find(".fancytree-title")[0].innerHTML;
$(helper).find(".fancytree-drag-helper-img").remove();
$(helper).find(".fancytree-title").replaceWith('<li class="ui-state-default tonga">' + foo + "</li>");
},
updateHelper: function(sourceNode, data) {},
draggable: {
appendTo: "body",
connectToSortable: "#mylist",
revert: "invalid",
containment: "document"
}
},
});
$("#mylist").sortable({
connectWith: "#mylist",
out: function(event, ui) {
if (event.originalEvent.type === "mousemove") {
$(ui.item).data('drugout', true);
}
}
}).disableSelection();
$(".tonga").draggable({
revert: true,
helper: "clone",
connectToFancytree: true,
start: function(event, ui) {
$(event.target).data('previndex', $(event.target).index());
},
stop: function(event, ui) {
if ($(event.target).data('drugout')) {
var originalIndex = $(event.target).data('previndex');
$("#mylist li:last").insertBefore($("#mylist li:eq(" + originalIndex + ")"));
}
}
});
$(".tonga").draggable({
revert: false,
helper: "original",
connectToSortable: "#mylist"
});
});
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/skin-win8/ui.fancytree.min.css" rel="stylesheet">
<!-- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.fancytree-all-deps.min.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.fancytree-all.min.js"></script>
</head>
<body>
<div id="tree"></div>
<ul id="mylist">
<li class="ui-state-default tonga">Item 1</li>
<li class="ui-state-default tonga">Item 2</li>
<li class="ui-state-default tonga">Item 3</li>
<li class="ui-state-default tonga">Item 4</li>
<li class="ui-state-default tonga">Item 5</li>
<li class="ui-state-default tonga">Item 6</li>
<li class="ui-state-default tonga">Item 7</li>
</ul>
</body>
Upvotes: 1