PDA

View Full Version : Ext.ux.MultiSelectTreePanel (with Drag and Drop)



Deadmeat
20 Jul 2009, 9:02 PM
This is a replacement tree component that supports multi-select and drag&drop at the same time. You can shift or ctrl select multiple nodes and drag identically to the normal tree. You can use further extensions to allow grids.

This code has moved to github (https://github.com/colinlear/ExtJS-3.x-Multiselect---Drag-Drop-Tree). The original links are still up, but may be removed in future.

This is the same as the extension for version 2.x at http://extjs.com/forum/showthread.php?t=60759

It seems to work as is with ExtJS 3.x with only two differences:


allowContainerDrop works correctly out of the box.
You no longer require the additional override code to fix insertion order.


If you find any bugs with ExtJS 3.x please post here.

This was originally posted as an example here (http://extjs.com/forum/showthread.php?t=28115)

There is a tree insertion order bug in 3.1.1 (http://www.extjs.com/forum/showthread.php?t=91506) reported below by tritonBear. There is an override in the bug thread.

In the latest version:

ExtJS 3.x is required.

Fixes an issue a user had with the way selection works. With the 1.1 release if you select multiple nodes and then later single click one of those nodes it doesn't do anything. The desired/intuitive behaviour was to deselect the other nodes. I implemented this with some messing around. I'm not entirely happy with how complicated it is. The end result is nicer though.

There is also a workaround for a bug in the core. If you click and hold a node for longer than the startdrag threshold then it calls proxy.repair() which causes some flickering.

Original live demo at: http://www.users.on.net/~clear/ext/

383257357@qq.com
1 Feb 2010, 10:01 PM
Thank you very much!

tritonBear
21 Feb 2010, 1:04 AM
Hi,

On v3.1.1 it seems drops are being placed incorrectly at the end of the list and not where it was placed within the nodes.

ex.

Folder
--A
--B
--C

drag B and drop above A produces:

Folder
--A
--C
--B

However, replacing the v3.1.1 ext.all.js with your version, v.2.2.1 ext-all-hacked.js fixes the problem and the drops are placed accordingly. Any insight on what the fix would be for 3.1.1?

Thanks in advance!

Deadmeat
3 Apr 2010, 1:40 AM
How odd. Looks like a bug in the 3.1.1 core. There is a demo here (http://www.users.on.net/~clear/ext/index-ext-3.1.1.html). One of the example tree is a vanilla tree (ie no multiselect) and shows the same issue.

This has fixed itself in ExtJS 3.2.0. I wonder what went wrong.

If you are still having problems (and tied to 3.1.1) I'll look into it and post and override you can use. See here (http://www.extjs.com/forum/showthread.php?t=91506).

Sorry I didn't post earlier. I didn't get an email for some reason.


Hi,

On v3.1.1 it seems drops are being placed incorrectly at the end of the list and not where it was placed within the nodes.

ex.

Folder
--A
--B
--C

drag B and drop above A produces:

Folder
--A
--C
--B

However, replacing the v3.1.1 ext.all.js with your version, v.2.2.1 ext-all-hacked.js fixes the problem and the drops are placed accordingly. Any insight on what the fix would be for 3.1.1?

Thanks in advance!

Deadmeat
4 Apr 2010, 4:15 AM
I've posted an updated beta version for anyone interested.

You get it here: http://www.users.on.net/~clear/ext/index-beta.html

The selection change is nice. If you've ever hated how single click on a selected node doesn't deselect all the other selected nodes, you should like it.

Also fixes a minor flickering issue.

Deadmeat
4 Apr 2010, 4:19 AM
Hi tritonBear,

Turns out it's a tree insertion order bug in the core version.

See bug and override fix here: http://www.extjs.com/forum/showthread.php?t=91506

Sorry I'm such a slacker and didn't see this (not subscribed to my own bug thread:()


Hi,

On v3.1.1 it seems drops are being placed incorrectly at the end of the list and not where it was placed within the nodes.

However, replacing the v3.1.1 ext.all.js with your version, v.2.2.1 ext-all-hacked.js fixes the problem and the drops are placed accordingly. Any insight on what the fix would be for 3.1.1?

WebM
20 Apr 2010, 5:35 AM
Single click deselection is very nice in the 1.2 Beta version, but I found a little bug too: If there are undraggable nodes in the selection, it won't work correctly, the nodes won't be deselected.

ninoguba
28 Oct 2010, 1:41 PM
There seems to be a bug in how the nodes are inserted when the nodes are dropped below a target node.

Ex:
1
2
3
4
5
6
7
8
9
0

Select nodes 6,7,8 and drop below node 1. The resulting order of the tree will be:

1
8
7
6
2
3
4
5
9
0

This happens on both 1.1 and 1.2 versions of this extension. I'm also using ExtJS 3.2.1 where this is happening. Would appreciate if someone can share the fix. I'll share the fix here as well once I managed to find a solution.

Thanks!

ninoguba
28 Oct 2010, 2:45 PM
I fixed the issue by adding the following override:



Ext.override(Ext.tree.TreeDropZone, {



// fix insertion order when inserting below
completeDrop : function(de){
var ns = de.dropNode, p = de.point, t = de.target;
if(!Ext.isArray(ns)){
ns = [ns];
}
var n;
for(var i = 0, len = ns.length; i < len; i++){
n = ns[i];
if(p == "above"){
t.parentNode.insertBefore(n, t);
}else if(p == "below"){
t.parentNode.insertBefore(n, t.nextSibling);
//Update target to make sure insertion order stays true to the original ordering
t = n;
}else{
t.appendChild(n);
}
}
n.ui.focus();
if(Ext.enableFx && this.tree.hlDrop){
n.ui.highlight();
}
t.ui.endDrop();
this.tree.fireEvent("nodedrop", de);
}
});




Please let me know if you find any adverse issues with this fix.

pit2011
14 Oct 2011, 1:30 AM
Hi,
is it possible to use this plugin in commercial projects? I know it has GPL licence, but maybe there is way to provide another licence like Apache Licence?

Thanks,
Jens

adam.jimenez
18 Sep 2012, 12:56 AM
This extension is excellent, thank you.

I found a bug where if you select the tree root and a bunch of nodes and then try to click one of them - the selection doesn't change. This is very apparent if you select all of the nodes including root and can't get back to single selection (unless you start ctrl-clicking to deselect first).

This is my fix:

change:

onNodeClick : function(node, e){
if (e.shiftKey) e.preventDefault();
// disable select unless not using a dragZone, or a multiselectdragzone
if ( !this.tree.dragZone || !this.tree.dragZone.isMultiSelect ) {
this.onMouseDown(node, e);
this.onMouseUp(node, e);
}
},
to:

onNodeClick : function(node, e){
if (e.shiftKey) e.preventDefault();
// disable select unless not using a dragZone, or a multiselectdragzone
if ( !this.tree.dragZone || !this.tree.dragZone.isMultiSelect || this.tree.root.isSelected() ) {
this.onMouseDown(node, e);
this.onMouseUp(node, e);
}
},

Deadmeat
2 Apr 2013, 7:10 AM
The actual bug seems to be related to selecting a non-draggable node(ie the root node, which is causing onBeforeDrag to return false.) Dragging the root node is going to cause bugs anyway.

I think even with your fix, so long as the root node (or any other non-draggable node) is selected, you still can't drag anything. Disabled nodes have the same problems, altho they shouldn't be able to be selected anyway.

The obvious fixes are:

Hide the root, making it unselectable.
Make all undraggable nodes unselectable by changing selectNode.
Filter the selected nodes to remove undraggable ones, and drag the rest.


The way the selection and drag work here is basically the wrong way to do it. The right way involves detecting mousedown/up events before the DD (drag/drop) code does (This happens in v4.2 at least). However that's not feasible with the ExtJS 3.x tree as far as I can determine.

I've uploaded the fix to the github repo (https://github.com/colinlear/ExtJS-3.x-Multiselect---Drag-Drop-Tree).

The change is here:



getUniqueSelectedNodes: function() {
var ret = [];
for (var c=0;c<this.selNodes.length;c++) {
var parent = this.selNodes[c];
if (!parent.draggable && !parent.disabled) continue; // skip root node...
ret.push(parent);
// nodes are sorted(?) so skip over subsequent nodes inside this one..
while ((c+1)<this.selNodes.length && parent.contains(this.selNodes[c+1])) c+;
}
return ret;
},


Sorry the reply has taken so long, apparently I don't get the emails anymore.


This extension is excellent, thank you.

I found a bug where if you select the tree root and a bunch of nodes and then try to click one of them - the selection doesn't change. This is very apparent if you select all of the nodes including root and can't get back to single selection (unless you start ctrl-clicking to deselect first).

gm.marwah@gmail.com
24 Jul 2013, 1:39 AM
Hi DeadMeat,
Does this solution works for ExtJS 4.1. As most of the classes and ux package seems to be out of date. Did you happen to upgrade the solution to 4.1, can you share with us ?

Thanks

Deadmeat
25 Jul 2013, 6:48 AM
Hi DeadMeat,
Does this solution works for ExtJS 4.1. As most of the classes and ux package seems to be out of date. Did you happen to upgrade the solution to 4.1, can you share with us ?

Thanks

This code isn't ported to ExtJS 4.x and isn't necessary either, since the default tree supports the main feature, and has several additional advantages besides.

4.1 has its own bugs, which aren't high on Sencha's priorities, but there is several examples out there on how to avoid/fix them.

E.G. https://github.com/colinlear/ExtJS-4.x-Tree-Drag-and-Drop-Fix

Basically this extension is EOL.