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 var pt = this.getDropPoint(e, n, dd);
117 // auto node expand check
118 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
119 this.queueExpand(node);
120 }else if(pt != "append"){
124 // set the insert point style on the target node
125 var returnCls = this.dropNotAllowed;
126 if(this.isValidDropPoint(n, pt, dd, e, data)){
131 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
132 cls = "x-tree-drag-insert-above";
133 }else if(pt == "below"){
134 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
135 cls = "x-tree-drag-insert-below";
137 returnCls = "x-tree-drop-ok-append";
138 cls = "x-tree-drag-append";
140 if(this.lastInsertClass != cls){
141 Roo.fly(el).replaceClass(this.lastInsertClass, cls);
142 this.lastInsertClass = cls;
149 onNodeOut : function(n, dd, e, data){
152 this.removeDropIndicators(n);
155 onNodeDrop : function(n, dd, e, data){
156 var point = this.getDropPoint(e, n, dd);
157 var targetNode = n.node;
158 targetNode.ui.startDrop();
159 if(!this.isValidDropPoint(n, point, dd, e, data)){
160 targetNode.ui.endDrop();
163 // first try to find the drop node
164 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
175 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
176 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
177 targetNode.ui.endDrop();
180 // allow target changing
181 targetNode = dropEvent.target;
182 if(point == "append" && !targetNode.isExpanded()){
183 targetNode.expand(false, null, function(){
184 this.completeDrop(dropEvent);
185 }.createDelegate(this));
187 this.completeDrop(dropEvent);
192 completeDrop : function(de){
193 var ns = de.dropNode, p = de.point, t = de.target;
194 if(!(ns instanceof Array)){
198 for(var i = 0, len = ns.length; i < len; i++){
201 t.parentNode.insertBefore(n, t);
202 }else if(p == "below"){
203 t.parentNode.insertBefore(n, t.nextSibling);
209 if(this.tree.hlDrop){
213 this.tree.fireEvent("nodedrop", de);
216 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
217 if(this.tree.hlDrop){
219 dropNode.ui.highlight();
221 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
224 getTree : function(){
228 removeDropIndicators : function(n){
231 Roo.fly(el).removeClass([
232 "x-tree-drag-insert-above",
233 "x-tree-drag-insert-below",
234 "x-tree-drag-append"]);
235 this.lastInsertClass = "_noclass";
239 beforeDragDrop : function(target, e, id){
244 afterRepair : function(data){
245 if(data && Roo.enableFx){
246 data.node.ui.highlight();