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){
80 return tn.allowChildren !== false ? "append" : false; // always append for root
83 var t = Roo.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
84 var y = Roo.lib.Event.getPageY(e);
85 //var noAppend = tn.allowChildren === false || tn.isLeaf();
87 // we may drop nodes anywhere, as long as allowChildren has not been set to false..
88 var noAppend = tn.allowChildren === false;
89 if(this.appendOnly || tn.parentNode.allowChildren === false){
90 return noAppend ? false : "append";
93 if(!this.allowParentInsert){
94 noBelow = tn.hasChildNodes() && tn.isExpanded();
96 var q = (b - t) / (noAppend ? 2 : 3);
97 if(y >= t && y < (t + q)){
99 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
106 onNodeEnter : function(n, dd, e, data){
110 onNodeOver : function(n, dd, e, data){
111 var pt = this.getDropPoint(e, n, dd);
114 // auto node expand check
115 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
116 this.queueExpand(node);
117 }else if(pt != "append"){
121 // set the insert point style on the target node
122 var returnCls = this.dropNotAllowed;
123 if(this.isValidDropPoint(n, pt, dd, e, data)){
128 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
129 cls = "x-tree-drag-insert-above";
130 }else if(pt == "below"){
131 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
132 cls = "x-tree-drag-insert-below";
134 returnCls = "x-tree-drop-ok-append";
135 cls = "x-tree-drag-append";
137 if(this.lastInsertClass != cls){
138 Roo.fly(el).replaceClass(this.lastInsertClass, cls);
139 this.lastInsertClass = cls;
146 onNodeOut : function(n, dd, e, data){
148 this.removeDropIndicators(n);
151 onNodeDrop : function(n, dd, e, data){
152 var point = this.getDropPoint(e, n, dd);
153 var targetNode = n.node;
154 targetNode.ui.startDrop();
155 if(!this.isValidDropPoint(n, point, dd, e, data)){
156 targetNode.ui.endDrop();
159 // first try to find the drop node
160 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
171 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
172 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
173 targetNode.ui.endDrop();
176 // allow target changing
177 targetNode = dropEvent.target;
178 if(point == "append" && !targetNode.isExpanded()){
179 targetNode.expand(false, null, function(){
180 this.completeDrop(dropEvent);
181 }.createDelegate(this));
183 this.completeDrop(dropEvent);
188 completeDrop : function(de){
189 var ns = de.dropNode, p = de.point, t = de.target;
190 if(!(ns instanceof Array)){
194 for(var i = 0, len = ns.length; i < len; i++){
197 t.parentNode.insertBefore(n, t);
198 }else if(p == "below"){
199 t.parentNode.insertBefore(n, t.nextSibling);
205 if(this.tree.hlDrop){
209 this.tree.fireEvent("nodedrop", de);
212 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
213 if(this.tree.hlDrop){
215 dropNode.ui.highlight();
217 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
220 getTree : function(){
224 removeDropIndicators : function(n){
227 Roo.fly(el).removeClass([
228 "x-tree-drag-insert-above",
229 "x-tree-drag-insert-below",
230 "x-tree-drag-append"]);
231 this.lastInsertClass = "_noclass";
235 beforeDragDrop : function(target, e, id){
240 afterRepair : function(data){
241 if(data && Roo.enableFx){
242 data.node.ui.highlight();