source: trunk/web/addons/job_monarch/lib/extjs/source/widgets/tree/TreeDropZone.js @ 619

Last change on this file since 619 was 619, checked in by ramonb, 15 years ago

lib/:

  • added new AJAX dependancies: ExtJS, pChart, Lightbox2
File size: 9.5 KB
Line 
1/*
2 * Ext JS Library 2.2.1
3 * Copyright(c) 2006-2009, Ext JS, LLC.
4 * licensing@extjs.com
5 *
6 * http://extjs.com/license
7 */
8
9/**
10 * @class Ext.tree.TreeDropZone
11 * @extends Ext.dd.DropZone
12 * @constructor
13 * @param {String/HTMLElement/Element} tree The {@link Ext.tree.TreePanel} for which to enable dropping
14 * @param {Object} config
15 */
16if(Ext.dd.DropZone){
17   
18Ext.tree.TreeDropZone = function(tree, config){
19    /**
20     * @cfg {Boolean} allowParentInsert
21     * Allow inserting a dragged node between an expanded parent node and its first child that will become a
22     * sibling of the parent when dropped (defaults to false)
23     */
24    this.allowParentInsert = false;
25    /**
26     * @cfg {String} allowContainerDrop
27     * True if drops on the tree container (outside of a specific tree node) are allowed (defaults to false)
28     */
29    this.allowContainerDrop = false;
30    /**
31     * @cfg {String} appendOnly
32     * True if the tree should only allow append drops (use for trees which are sorted, defaults to false)
33     */
34    this.appendOnly = false;
35    Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.innerCt, config);
36    /**
37    * The TreePanel for this drop zone
38    * @type Ext.tree.TreePanel
39    * @property
40    */
41    this.tree = tree;
42    /**
43    * Arbitrary data that can be associated with this tree and will be included in the event object that gets
44    * passed to any nodedragover event handler (defaults to {})
45    * @type Ext.tree.TreePanel
46    * @property
47    */
48    this.dragOverData = {};
49    // private
50    this.lastInsertClass = "x-tree-no-status";
51};
52
53Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
54    /**
55     * @cfg {String} ddGroup
56     * A named drag drop group to which this object belongs.  If a group is specified, then this object will only
57     * interact with other drag drop objects in the same group (defaults to 'TreeDD').
58     */
59    ddGroup : "TreeDD",
60
61    /**
62     * @cfg {String} expandDelay
63     * The delay in milliseconds to wait before expanding a target tree node while dragging a droppable node
64     * over the target (defaults to 1000)
65     */
66    expandDelay : 1000,
67
68    // private
69    expandNode : function(node){
70        if(node.hasChildNodes() && !node.isExpanded()){
71            node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
72        }
73    },
74
75    // private
76    queueExpand : function(node){
77        this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
78    },
79
80    // private
81    cancelExpand : function(){
82        if(this.expandProcId){
83            clearTimeout(this.expandProcId);
84            this.expandProcId = false;
85        }
86    },
87
88    // private
89    isValidDropPoint : function(n, pt, dd, e, data){
90        if(!n || !data){ return false; }
91        var targetNode = n.node;
92        var dropNode = data.node;
93        // default drop rules
94        if(!(targetNode && targetNode.isTarget && pt)){
95            return false;
96        }
97        if(pt == "append" && targetNode.allowChildren === false){
98            return false;
99        }
100        if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
101            return false;
102        }
103        if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
104            return false;
105        }
106        // reuse the object
107        var overEvent = this.dragOverData;
108        overEvent.tree = this.tree;
109        overEvent.target = targetNode;
110        overEvent.data = data;
111        overEvent.point = pt;
112        overEvent.source = dd;
113        overEvent.rawEvent = e;
114        overEvent.dropNode = dropNode;
115        overEvent.cancel = false; 
116        var result = this.tree.fireEvent("nodedragover", overEvent);
117        return overEvent.cancel === false && result !== false;
118    },
119
120    // private
121    getDropPoint : function(e, n, dd){
122        var tn = n.node;
123        if(tn.isRoot){
124            return tn.allowChildren !== false ? "append" : false; // always append for root
125        }
126        var dragEl = n.ddel;
127        var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
128        var y = Ext.lib.Event.getPageY(e);
129        var noAppend = tn.allowChildren === false || tn.isLeaf();
130        if(this.appendOnly || tn.parentNode.allowChildren === false){
131            return noAppend ? false : "append";
132        }
133        var noBelow = false;
134        if(!this.allowParentInsert){
135            noBelow = tn.hasChildNodes() && tn.isExpanded();
136        }
137        var q = (b - t) / (noAppend ? 2 : 3);
138        if(y >= t && y < (t + q)){
139            return "above";
140        }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
141            return "below";
142        }else{
143            return "append";
144        }
145    },
146
147    // private
148    onNodeEnter : function(n, dd, e, data){
149        this.cancelExpand();
150    },
151
152    // private
153    onNodeOver : function(n, dd, e, data){
154        var pt = this.getDropPoint(e, n, dd);
155        var node = n.node;
156       
157        // auto node expand check
158        if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
159            this.queueExpand(node);
160        }else if(pt != "append"){
161            this.cancelExpand();
162        }
163       
164        // set the insert point style on the target node
165        var returnCls = this.dropNotAllowed;
166        if(this.isValidDropPoint(n, pt, dd, e, data)){
167           if(pt){
168               var el = n.ddel;
169               var cls;
170               if(pt == "above"){
171                   returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
172                   cls = "x-tree-drag-insert-above";
173               }else if(pt == "below"){
174                   returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
175                   cls = "x-tree-drag-insert-below";
176               }else{
177                   returnCls = "x-tree-drop-ok-append";
178                   cls = "x-tree-drag-append";
179               }
180               if(this.lastInsertClass != cls){
181                   Ext.fly(el).replaceClass(this.lastInsertClass, cls);
182                   this.lastInsertClass = cls;
183               }
184           }
185       }
186       return returnCls;
187    },
188
189    // private
190    onNodeOut : function(n, dd, e, data){
191        this.cancelExpand();
192        this.removeDropIndicators(n);
193    },
194
195    // private
196    onNodeDrop : function(n, dd, e, data){
197        var point = this.getDropPoint(e, n, dd);
198        var targetNode = n.node;
199        targetNode.ui.startDrop();
200        if(!this.isValidDropPoint(n, point, dd, e, data)){
201            targetNode.ui.endDrop();
202            return false;
203        }
204        // first try to find the drop node
205        var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
206        var dropEvent = {
207            tree : this.tree,
208            target: targetNode,
209            data: data,
210            point: point,
211            source: dd,
212            rawEvent: e,
213            dropNode: dropNode,
214            cancel: !dropNode,
215            dropStatus: false
216        };
217        var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
218        if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
219            targetNode.ui.endDrop();
220            return dropEvent.dropStatus;
221        }
222        // allow target changing
223        targetNode = dropEvent.target;
224        if(point == "append" && !targetNode.isExpanded()){
225            targetNode.expand(false, null, function(){
226                this.completeDrop(dropEvent);
227            }.createDelegate(this));
228        }else{
229            this.completeDrop(dropEvent);
230        }
231        return true;
232    },
233
234    // private
235    completeDrop : function(de){
236        var ns = de.dropNode, p = de.point, t = de.target;
237        if(!Ext.isArray(ns)){
238            ns = [ns];
239        }
240        var n;
241        for(var i = 0, len = ns.length; i < len; i++){
242            n = ns[i];
243            if(p == "above"){
244                t.parentNode.insertBefore(n, t);
245            }else if(p == "below"){
246                t.parentNode.insertBefore(n, t.nextSibling);
247            }else{
248                t.appendChild(n);
249            }
250        }
251        n.ui.focus();
252        if(Ext.enableFx && this.tree.hlDrop){
253            n.ui.highlight();
254        }
255        t.ui.endDrop();
256        this.tree.fireEvent("nodedrop", de);
257    },
258
259    // private
260    afterNodeMoved : function(dd, data, e, targetNode, dropNode){
261        if(Ext.enableFx && this.tree.hlDrop){
262            dropNode.ui.focus();
263            dropNode.ui.highlight();
264        }
265        this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
266    },
267
268    // private
269    getTree : function(){
270        return this.tree;
271    },
272
273    // private
274    removeDropIndicators : function(n){
275        if(n && n.ddel){
276            var el = n.ddel;
277            Ext.fly(el).removeClass([
278                    "x-tree-drag-insert-above",
279                    "x-tree-drag-insert-below",
280                    "x-tree-drag-append"]);
281            this.lastInsertClass = "_noclass";
282        }
283    },
284
285    // private
286    beforeDragDrop : function(target, e, id){
287        this.cancelExpand();
288        return true;
289    },
290
291    // private
292    afterRepair : function(data){
293        if(data && Ext.enableFx){
294            data.node.ui.highlight();
295        }
296        this.hideProxy();
297    }   
298});
299
300}
Note: See TracBrowser for help on using the repository browser.