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, {
29 expandNode : function(node){
30 if(node.hasChildNodes() && !node.isExpanded()){
31 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
35 queueExpand : function(node){
36 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
39 cancelExpand : function(){
40 if(this.expandProcId){
41 clearTimeout(this.expandProcId);
42 this.expandProcId = false;
46 isValidDropPoint : function(n, pt, dd, e, data){
47 if(!n || !data){ return false; }
48 var targetNode = n.node;
49 var dropNode = data.node;
51 if(!(targetNode && targetNode.isTarget && pt)){
54 if(pt == "append" && targetNode.allowChildren === false){
57 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
60 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
64 var overEvent = this.dragOverData;
65 overEvent.tree = this.tree;
66 overEvent.target = targetNode;
67 overEvent.data = data;
69 overEvent.source = dd;
70 overEvent.rawEvent = e;
71 overEvent.dropNode = dropNode;
72 overEvent.cancel = false;
73 var result = this.tree.fireEvent("nodedragover", overEvent);
74 return overEvent.cancel === false && result !== false;
77 getDropPoint : function(e, n, dd)
81 return tn.allowChildren !== false ? "append" : false; // always append for root
84 var t = Roo.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
85 var y = Roo.lib.Event.getPageY(e);
86 //var noAppend = tn.allowChildren === false || tn.isLeaf();
88 // we may drop nodes anywhere, as long as allowChildren has not been set to false..
89 var noAppend = tn.allowChildren === false;
90 if(this.appendOnly || tn.parentNode.allowChildren === false){
91 return noAppend ? false : "append";
94 if(!this.allowParentInsert){
95 noBelow = tn.hasChildNodes() && tn.isExpanded();
97 var q = (b - t) / (noAppend ? 2 : 3);
98 if(y >= t && y < (t + q)){
100 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
107 onNodeEnter : function(n, dd, e, data)
112 onNodeOver : function(n, dd, e, data)
114 Roo.log('node over');
115 var pt = this.getDropPoint(e, n, dd);
118 // auto node expand check
119 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
120 this.queueExpand(node);
121 }else if(pt != "append"){
125 // set the insert point style on the target node
126 var returnCls = this.dropNotAllowed;
127 if(this.isValidDropPoint(n, pt, dd, e, data)){
132 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
133 cls = "x-tree-drag-insert-above";
134 }else if(pt == "below"){
135 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
136 cls = "x-tree-drag-insert-below";
138 returnCls = "x-tree-drop-ok-append";
139 cls = "x-tree-drag-append";
141 if(this.lastInsertClass != cls){
142 Roo.fly(el).replaceClass(this.lastInsertClass, cls);
143 this.lastInsertClass = cls;
150 onNodeOut : function(n, dd, e, data){
153 this.removeDropIndicators(n);
156 onNodeDrop : function(n, dd, e, data){
157 var point = this.getDropPoint(e, n, dd);
158 var targetNode = n.node;
159 targetNode.ui.startDrop();
160 if(!this.isValidDropPoint(n, point, dd, e, data)){
161 targetNode.ui.endDrop();
164 // first try to find the drop node
165 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
176 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
177 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
178 targetNode.ui.endDrop();
181 // allow target changing
182 targetNode = dropEvent.target;
183 if(point == "append" && !targetNode.isExpanded()){
184 targetNode.expand(false, null, function(){
185 this.completeDrop(dropEvent);
186 }.createDelegate(this));
188 this.completeDrop(dropEvent);
193 completeDrop : function(de){
194 var ns = de.dropNode, p = de.point, t = de.target;
195 if(!(ns instanceof Array)){
199 for(var i = 0, len = ns.length; i < len; i++){
202 t.parentNode.insertBefore(n, t);
203 }else if(p == "below"){
204 t.parentNode.insertBefore(n, t.nextSibling);
210 if(this.tree.hlDrop){
214 this.tree.fireEvent("nodedrop", de);
217 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
218 if(this.tree.hlDrop){
220 dropNode.ui.highlight();
222 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
225 getTree : function(){
229 removeDropIndicators : function(n){
232 Roo.fly(el).removeClass([
233 "x-tree-drag-insert-above",
234 "x-tree-drag-insert-below",
235 "x-tree-drag-append"]);
236 this.lastInsertClass = "_noclass";
240 beforeDragDrop : function(target, e, id){
245 afterRepair : function(data){
246 if(data && Roo.enableFx){
247 data.node.ui.highlight();