4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
14 Roo.tree.TreeDropZone = function(tree, config){
15 this.allowParentInsert = false;
16 this.allowContainerDrop = false;
17 this.appendOnly = false;
18 Roo.tree.TreeDropZone.superclass.constructor.call(this, tree.innerCt, config);
20 this.lastInsertClass = "x-tree-no-status";
21 this.dragOverData = {};
24 Roo.extend(Roo.tree.TreeDropZone, Roo.dd.DropZone, {
30 expandNode : function(node){
31 if(node.hasChildNodes() && !node.isExpanded()){
32 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
36 queueExpand : function(node){
37 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
40 cancelExpand : function(){
41 if(this.expandProcId){
42 clearTimeout(this.expandProcId);
43 this.expandProcId = false;
47 isValidDropPoint : function(n, pt, dd, e, data){
48 if(!n || !data){ return false; }
49 var targetNode = n.node;
50 var dropNode = data.node;
52 if(!(targetNode && targetNode.isTarget && pt)){
55 if(pt == "append" && targetNode.allowChildren === false){
58 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
61 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
65 var overEvent = this.dragOverData;
66 overEvent.tree = this.tree;
67 overEvent.target = targetNode;
68 overEvent.data = data;
70 overEvent.source = dd;
71 overEvent.rawEvent = e;
72 overEvent.dropNode = dropNode;
73 overEvent.cancel = false;
74 var result = this.tree.fireEvent("nodedragover", overEvent);
75 return overEvent.cancel === false && result !== false;
78 getDropPoint : function(e, n, dd)
82 return tn.allowChildren !== false ? "append" : false; // always append for root
85 var t = Roo.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
86 var y = Roo.lib.Event.getPageY(e);
87 //var noAppend = tn.allowChildren === false || tn.isLeaf();
89 // we may drop nodes anywhere, as long as allowChildren has not been set to false..
90 var noAppend = tn.allowChildren === false;
91 if(this.appendOnly || tn.parentNode.allowChildren === false){
92 return noAppend ? false : "append";
95 if(!this.allowParentInsert){
96 noBelow = tn.hasChildNodes() && tn.isExpanded();
98 var q = (b - t) / (noAppend ? 2 : 3);
99 if(y >= t && y < (t + q)){
101 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
108 onNodeEnter : function(n, dd, e, data)
113 onNodeOver : function(n, dd, e, data)
116 var pt = this.getDropPoint(e, n, dd);
119 // auto node expand check
120 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
121 this.queueExpand(node);
122 }else if(pt != "append"){
126 // set the insert point style on the target node
127 var returnCls = this.dropNotAllowed;
128 if(this.isValidDropPoint(n, pt, dd, e, data)){
133 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
134 cls = "x-tree-drag-insert-above";
135 }else if(pt == "below"){
136 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
137 cls = "x-tree-drag-insert-below";
139 returnCls = "x-tree-drop-ok-append";
140 cls = "x-tree-drag-append";
142 if(this.lastInsertClass != cls){
143 Roo.fly(el).replaceClass(this.lastInsertClass, cls);
144 this.lastInsertClass = cls;
151 onNodeOut : function(n, dd, e, data){
154 this.removeDropIndicators(n);
157 onNodeDrop : function(n, dd, e, data){
158 var point = this.getDropPoint(e, n, dd);
159 var targetNode = n.node;
160 targetNode.ui.startDrop();
161 if(!this.isValidDropPoint(n, point, dd, e, data)){
162 targetNode.ui.endDrop();
165 // first try to find the drop node
166 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
177 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
178 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
179 targetNode.ui.endDrop();
182 // allow target changing
183 targetNode = dropEvent.target;
184 if(point == "append" && !targetNode.isExpanded()){
185 targetNode.expand(false, null, function(){
186 this.completeDrop(dropEvent);
187 }.createDelegate(this));
189 this.completeDrop(dropEvent);
194 completeDrop : function(de){
195 var ns = de.dropNode, p = de.point, t = de.target;
196 if(!(ns instanceof Array)){
200 for(var i = 0, len = ns.length; i < len; i++){
203 t.parentNode.insertBefore(n, t);
204 }else if(p == "below"){
205 t.parentNode.insertBefore(n, t.nextSibling);
211 if(this.tree.hlDrop){
215 this.tree.fireEvent("nodedrop", de);
218 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
219 if(this.tree.hlDrop){
221 dropNode.ui.highlight();
223 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
226 getTree : function(){
230 removeDropIndicators : function(n){
233 Roo.fly(el).removeClass([
234 "x-tree-drag-insert-above",
235 "x-tree-drag-insert-below",
236 "x-tree-drag-append"]);
237 this.lastInsertClass = "_noclass";
241 beforeDragDrop : function(target, e, id){
246 afterRepair : function(data){
247 if(data && Roo.enableFx){
248 data.node.ui.highlight();