PDA

View Full Version : Tree DnD issue with rootVisible: false


rad_nq
07-23-2007, 03:07 PM
The problem came up when I was trying to create a simple List widget using the Tree as a base. Tree already provides the icon, renaming as well as DnD with minimal code as we already have proper trees elsewhere in the interface.

However the issue is if you make the TreePanel with "rootVisible: false" you cannot drop *any* content into it.
It appears that you can only drop a tree node onto another tree node, and not into the TreePanel container whitespace. This is correct behavior if the root is visible, but when root is not visible the whole panel *is* the root's content so you should be able to drop anywhere within it.

Is this something that will be fixed, or is it functioning as designed and we should use Grid instead?

Example code:
<html>
<head>
<title>TreeTest</title>
(now include paths to ext-all-debug.js and the basic CSS)

<style type="text/css">
.basicTree {
border: 1px solid black;
float: left;
width: 200px;
height: 150px;
padding: 1px;
background-color: white;
margin-right: 50px;
overflow: auto;
}
</style>
<script type="text/javascript">
function init(){
var treeConfig = {
animate: false,
enableDD: true,
rootVisible: true,
ddAppendOnly: true,
lines: false,
ddGroup: 'groupEdit'
};

var availRoot = new Ext.tree.TreeNode({text: '--Available--', allowDrag: false, allowDrop: true, draggable: false, expanded: true});
var assignRoot = new Ext.tree.TreeNode({text: '--Assign--', allowDrag: false, allowDrop: true, draggable: false, expanded: true});
availRoot.appendChild(new Ext.tree.TreeNode({text: 'node1', allowDrop: false}));
availRoot.appendChild(new Ext.tree.TreeNode({text: 'node2', allowDrop: false}));
availRoot.appendChild(new Ext.tree.TreeNode({text: 'node3', allowDrop: false}));


var tree1 = new Ext.tree.TreePanel('tree1', treeConfig);
var tree2 = new Ext.tree.TreePanel('tree2', treeConfig);
tree1.setRootNode(availRoot);
tree2.setRootNode(assignRoot);

tree1.render();
tree2.render();
}
Ext.EventManager.onDocumentReady(init, window, true);
</script>
</head>
<body >
<div id="tree1" class="basicTree"></div>
<div id="tree2" class="basicTree"></div>
</body>
</html>

jack.slocum
07-23-2007, 04:29 PM
There needs to be a node to drop on in order to use default drag and drop. This is not a bug, you need a node to append to/insert before/after - that is how a tree works. It is a tree drag and drop, not a div drag and drop but....

Behind the scenes there is a standard div drag drop, so you can do something to enable the behavior you desire:

tree.dropZone.onContainerDrop = function(...

This function will notify you when something is dropped on the tree's container element.

Take a look at:

http://extjs.com/deploy/ext/docs/output/Ext.dd.DropZone.html#onContainerDrop

rad_nq
07-24-2007, 08:16 AM
Thanks.
Unfortunately the onContainerDrop sort of works. The <div> with the tree is within a <td> and as a result the onContainerDrop is only invoked when the cursor is on a 1 pixel border between the div and the td. I get the feeling what is required is changing the DropZone and registering the tree's element itself with Ext.dd.Registry to get the behavior required. Alas the burden of project requirements.

ivaylo.bakalov
07-24-2007, 10:37 AM
rad_nq,

Here is one way to setup your tree and it's container to allow drop when the tree root is empty and hidden:


function setupTreePanel(container, content, text)
{
if ( text )
{
content =
[{
text: text,
leaf: false,
iconCls: "a-folder",
expanded: true,
children: content
}]
}
var tree = new T.TreePanel(container,
{
animate: false,
loader: new T.TreeLoader(),
enableDD: true,
containerScroll: true,
rootVisible: false,
ddGroup: ddGroup
});
tree.setRootNode(new T.AsyncTreeNode(
{
text: text,
leaf: false,
draggable: false,
expanded: true,
iconCls: "a-folder",
children: content
}));
tree.render();
tree.on("contextmenu", this.menuEx);
setupEmptyTreeDrop(container, tree, tree.root);
return tree;
}

function setupEmptyTreeDrop(container, tree, root)
{
var dropTarget = new D.DropTarget(Ext.get(container),
{
ddGroup: tree.ddGroup,
dropAllowed: "x-tree-drop-ok-append"
});
dropTarget.notifyDrop = function(dd, e, data)
{
if(data.node)
{
root.appendChild(data.node);
}
return true;
}
dropTarget.isTarget = (! root.firstChild);
if ( Ext.isIE )
{
tree.getEl().select("ul.x-tree-root-ct").addClass("a-zero-height");
}
root.on("remove", function(tree, root)
{
dropTarget.isTarget = (! root.firstChild);
});

root.on("append", function()
{
dropTarget.isTarget = false;
});
}

jack.slocum
07-25-2007, 06:47 AM
That's nice ivaylo. Thanks for sharing!