Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / src / dd / DragZone.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.dd.DragZone
17  * @extends Ext.dd.DragSource
18  * <p>This class provides a container DD instance that allows dragging of multiple child source nodes.</p>
19  * <p>This class does not move the drag target nodes, but a proxy element which may contain
20  * any DOM structure you wish. The DOM element to show in the proxy is provided by either a
21  * provided implementation of {@link #getDragData}, or by registered draggables registered with {@link Ext.dd.Registry}</p>
22  * <p>If you wish to provide draggability for an arbitrary number of DOM nodes, each of which represent some
23  * application object (For example nodes in a {@link Ext.view.View DataView}) then use of this class
24  * is the most efficient way to "activate" those nodes.</p>
25  * <p>By default, this class requires that draggable child nodes are registered with {@link Ext.dd.Registry}.
26  * However a simpler way to allow a DragZone to manage any number of draggable elements is to configure
27  * the DragZone with  an implementation of the {@link #getDragData} method which interrogates the passed
28  * mouse event to see if it has taken place within an element, or class of elements. This is easily done
29  * by using the event's {@link Ext.EventObject#getTarget getTarget} method to identify a node based on a
30  * {@link Ext.DomQuery} selector. For example, to make the nodes of a DataView draggable, use the following
31  * technique. Knowledge of the use of the DataView is required:</p><pre><code>
32 myDataView.on('render', function(v) {
33     myDataView.dragZone = new Ext.dd.DragZone(v.getEl(), {
34
35 //      On receipt of a mousedown event, see if it is within a DataView node.
36 //      Return a drag data object if so.
37         getDragData: function(e) {
38
39 //          Use the DataView's own itemSelector (a mandatory property) to
40 //          test if the mousedown is within one of the DataView's nodes.
41             var sourceEl = e.getTarget(v.itemSelector, 10);
42
43 //          If the mousedown is within a DataView node, clone the node to produce
44 //          a ddel element for use by the drag proxy. Also add application data
45 //          to the returned data object.
46             if (sourceEl) {
47                 d = sourceEl.cloneNode(true);
48                 d.id = Ext.id();
49                 return {
50                     ddel: d,
51                     sourceEl: sourceEl,
52                     repairXY: Ext.fly(sourceEl).getXY(),
53                     sourceStore: v.store,
54                     draggedRecord: v.{@link Ext.view.View#getRecord getRecord}(sourceEl)
55                 }
56             }
57         },
58
59 //      Provide coordinates for the proxy to slide back to on failed drag.
60 //      This is the original XY coordinates of the draggable element captured
61 //      in the getDragData method.
62         getRepairXY: function() {
63             return this.dragData.repairXY;
64         }
65     });
66 });</code></pre>
67  * See the {@link Ext.dd.DropZone DropZone} documentation for details about building a DropZone which
68  * cooperates with this DragZone.
69  */
70 Ext.define('Ext.dd.DragZone', {
71
72     extend: 'Ext.dd.DragSource',
73
74     /**
75      * Creates new DragZone.
76      * @param {String/HTMLElement/Ext.Element} el The container element or ID of it.
77      * @param {Object} config
78      */
79     constructor : function(el, config){
80         this.callParent([el, config]);
81         if (this.containerScroll) {
82             Ext.dd.ScrollManager.register(this.el);
83         }
84     },
85
86     /**
87      * This property contains the data representing the dragged object. This data is set up by the implementation
88      * of the {@link #getDragData} method. It must contain a <tt>ddel</tt> property, but can contain
89      * any other data according to the application's needs.
90      * @type Object
91      * @property dragData
92      */
93
94     /**
95      * @cfg {Boolean} containerScroll True to register this container with the Scrollmanager
96      * for auto scrolling during drag operations.
97      */
98
99     /**
100      * Called when a mousedown occurs in this container. Looks in {@link Ext.dd.Registry}
101      * for a valid target to drag based on the mouse down. Override this method
102      * to provide your own lookup logic (e.g. finding a child by class name). Make sure your returned
103      * object has a "ddel" attribute (with an HTML Element) for other functions to work.
104      * @param {Event} e The mouse down event
105      * @return {Object} The dragData
106      */
107     getDragData : function(e){
108         return Ext.dd.Registry.getHandleFromEvent(e);
109     },
110
111     /**
112      * Called once drag threshold has been reached to initialize the proxy element. By default, it clones the
113      * this.dragData.ddel
114      * @param {Number} x The x position of the click on the dragged object
115      * @param {Number} y The y position of the click on the dragged object
116      * @return {Boolean} true to continue the drag, false to cancel
117      */
118     onInitDrag : function(x, y){
119         this.proxy.update(this.dragData.ddel.cloneNode(true));
120         this.onStartDrag(x, y);
121         return true;
122     },
123
124     /**
125      * Called after a repair of an invalid drop. By default, highlights this.dragData.ddel
126      */
127     afterRepair : function(){
128         var me = this;
129         if (Ext.enableFx) {
130             Ext.fly(me.dragData.ddel).highlight(me.repairHighlightColor);
131         }
132         me.dragging = false;
133     },
134
135     /**
136      * Called before a repair of an invalid drop to get the XY to animate to. By default returns
137      * the XY of this.dragData.ddel
138      * @param {Event} e The mouse up event
139      * @return {Number[]} The xy location (e.g. [100, 200])
140      */
141     getRepairXY : function(e){
142         return Ext.Element.fly(this.dragData.ddel).getXY();
143     },
144
145     destroy : function(){
146         this.callParent();
147         if (this.containerScroll) {
148             Ext.dd.ScrollManager.unregister(this.el);
149         }
150     }
151 });
152