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">
13 * @class Roo.dd.DragSource
14 * @extends Roo.dd.DDProxy
15 * A simple class that provides the basic implementation needed to make any element draggable.
17 * @param {String/HTMLElement/Element} el The container element
18 * @param {Object} config
20 Roo.dd.DragSource = function(el, config){
21 this.el = Roo.get(el);
24 Roo.apply(this, config);
27 this.proxy = new Roo.dd.StatusProxy();
30 Roo.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
31 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
33 this.dragging = false;
36 Roo.extend(Roo.dd.DragSource, Roo.dd.DDProxy, {
38 * @cfg {String} dropAllowed
39 * The CSS class returned to the drag source when drop is allowed (defaults to "x-dd-drop-ok").
41 dropAllowed : "x-dd-drop-ok",
43 * @cfg {String} dropNotAllowed
44 * The CSS class returned to the drag source when drop is not allowed (defaults to "x-dd-drop-nodrop").
46 dropNotAllowed : "x-dd-drop-nodrop",
49 * Returns the data object associated with this drag source
50 * @return {Object} data An object containing arbitrary data
52 getDragData : function(e){
57 onDragEnter : function(e, id){
58 var target = Roo.dd.DragDropMgr.getDDById(id);
59 this.cachedTarget = target;
60 if(this.beforeDragEnter(target, e, id) !== false){
61 if(target.isNotifyTarget){
62 var status = target.notifyEnter(this, e, this.dragData);
63 this.proxy.setStatus(status);
65 this.proxy.setStatus(this.dropAllowed);
68 if(this.afterDragEnter){
70 * An empty function by default, but provided so that you can perform a custom action
71 * when the dragged item enters the drop target by providing an implementation.
72 * @param {Roo.dd.DragDrop} target The drop target
73 * @param {Event} e The event object
74 * @param {String} id The id of the dragged element
75 * @method afterDragEnter
77 this.afterDragEnter(target, e, id);
83 * An empty function by default, but provided so that you can perform a custom action
84 * before the dragged item enters the drop target and optionally cancel the onDragEnter.
85 * @param {Roo.dd.DragDrop} target The drop target
86 * @param {Event} e The event object
87 * @param {String} id The id of the dragged element
88 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
90 beforeDragEnter : function(target, e, id){
95 alignElWithMouse: function() {
96 Roo.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
101 onDragOver : function(e, id){
102 var target = this.cachedTarget || Roo.dd.DragDropMgr.getDDById(id);
103 if(this.beforeDragOver(target, e, id) !== false){
104 if(target.isNotifyTarget){
105 var status = target.notifyOver(this, e, this.dragData);
106 this.proxy.setStatus(status);
109 if(this.afterDragOver){
111 * An empty function by default, but provided so that you can perform a custom action
112 * while the dragged item is over the drop target by providing an implementation.
113 * @param {Roo.dd.DragDrop} target The drop target
114 * @param {Event} e The event object
115 * @param {String} id The id of the dragged element
116 * @method afterDragOver
118 this.afterDragOver(target, e, id);
124 * An empty function by default, but provided so that you can perform a custom action
125 * while the dragged item is over the drop target and optionally cancel the onDragOver.
126 * @param {Roo.dd.DragDrop} target The drop target
127 * @param {Event} e The event object
128 * @param {String} id The id of the dragged element
129 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
131 beforeDragOver : function(target, e, id){
136 onDragOut : function(e, id){
137 var target = this.cachedTarget || Roo.dd.DragDropMgr.getDDById(id);
138 if(this.beforeDragOut(target, e, id) !== false){
139 if(target.isNotifyTarget){
140 target.notifyOut(this, e, this.dragData);
143 if(this.afterDragOut){
145 * An empty function by default, but provided so that you can perform a custom action
146 * after the dragged item is dragged out of the target without dropping.
147 * @param {Roo.dd.DragDrop} target The drop target
148 * @param {Event} e The event object
149 * @param {String} id The id of the dragged element
150 * @method afterDragOut
152 this.afterDragOut(target, e, id);
155 this.cachedTarget = null;
159 * An empty function by default, but provided so that you can perform a custom action before the dragged
160 * item is dragged out of the target without dropping, and optionally cancel the onDragOut.
161 * @param {Roo.dd.DragDrop} target The drop target
162 * @param {Event} e The event object
163 * @param {String} id The id of the dragged element
164 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
166 beforeDragOut : function(target, e, id){
171 onDragDrop : function(e, id){
172 var target = this.cachedTarget || Roo.dd.DragDropMgr.getDDById(id);
173 if(this.beforeDragDrop(target, e, id) !== false){
174 if(target.isNotifyTarget){
175 if(target.notifyDrop(this, e, this.dragData)){ // valid drop?
176 this.onValidDrop(target, e, id);
178 this.onInvalidDrop(target, e, id);
181 this.onValidDrop(target, e, id);
184 if(this.afterDragDrop){
186 * An empty function by default, but provided so that you can perform a custom action
187 * after a valid drag drop has occurred by providing an implementation.
188 * @param {Roo.dd.DragDrop} target The drop target
189 * @param {Event} e The event object
190 * @param {String} id The id of the dropped element
191 * @method afterDragDrop
193 this.afterDragDrop(target, e, id);
196 delete this.cachedTarget;
200 * An empty function by default, but provided so that you can perform a custom action before the dragged
201 * item is dropped onto the target and optionally cancel the onDragDrop.
202 * @param {Roo.dd.DragDrop} target The drop target
203 * @param {Event} e The event object
204 * @param {String} id The id of the dragged element
205 * @return {Boolean} isValid True if the drag drop event is valid, else false to cancel
207 beforeDragDrop : function(target, e, id){
212 onValidDrop : function(target, e, id){
214 if(this.afterValidDrop){
216 * An empty function by default, but provided so that you can perform a custom action
217 * after a valid drop has occurred by providing an implementation.
218 * @param {Object} target The target DD
219 * @param {Event} e The event object
220 * @param {String} id The id of the dropped element
221 * @method afterInvalidDrop
223 this.afterValidDrop(target, e, id);
228 getRepairXY : function(e, data){
229 return this.el.getXY();
233 onInvalidDrop : function(target, e, id){
234 this.beforeInvalidDrop(target, e, id);
235 if(this.cachedTarget){
236 if(this.cachedTarget.isNotifyTarget){
237 this.cachedTarget.notifyOut(this, e, this.dragData);
239 this.cacheTarget = null;
241 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
243 if(this.afterInvalidDrop){
245 * An empty function by default, but provided so that you can perform a custom action
246 * after an invalid drop has occurred by providing an implementation.
247 * @param {Event} e The event object
248 * @param {String} id The id of the dropped element
249 * @method afterInvalidDrop
251 this.afterInvalidDrop(e, id);
256 afterRepair : function(){
258 this.el.highlight(this.hlColor || "c3daf9");
260 this.dragging = false;
264 * An empty function by default, but provided so that you can perform a custom action after an invalid
266 * @param {Roo.dd.DragDrop} target The drop target
267 * @param {Event} e The event object
268 * @param {String} id The id of the dragged element
269 * @return {Boolean} isValid True if the invalid drop should proceed, else false to cancel
271 beforeInvalidDrop : function(target, e, id){
276 handleMouseDown : function(e){
280 var data = this.getDragData(e);
281 if(data && this.onBeforeDrag(data, e) !== false){
282 this.dragData = data;
284 Roo.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
289 * An empty function by default, but provided so that you can perform a custom action before the initial
290 * drag event begins and optionally cancel it.
291 * @param {Object} data An object containing arbitrary data to be shared with drop targets
292 * @param {Event} e The event object
293 * @return {Boolean} isValid True if the drag event is valid, else false to cancel
295 onBeforeDrag : function(data, e){
300 * An empty function by default, but provided so that you can perform a custom action once the initial
301 * drag event has begun. The drag cannot be canceled from this function.
302 * @param {Number} x The x position of the click on the dragged object
303 * @param {Number} y The y position of the click on the dragged object
305 onStartDrag : Roo.emptyFn,
307 // private - YUI override
308 startDrag : function(x, y){
310 this.dragging = true;
311 this.proxy.update("");
312 this.onInitDrag(x, y);
317 onInitDrag : function(x, y){
318 var clone = this.el.dom.cloneNode(true);
319 clone.id = Roo.id(); // prevent duplicate ids
320 this.proxy.update(clone);
321 this.onStartDrag(x, y);
326 * Returns the drag source's underlying {@link Roo.dd.StatusProxy}
327 * @return {Roo.dd.StatusProxy} proxy The StatusProxy
329 getProxy : function(){
334 * Hides the drag source's {@link Roo.dd.StatusProxy}
336 hideProxy : function(){
338 this.proxy.reset(true);
339 this.dragging = false;
343 triggerCacheRefresh : function(){
344 Roo.dd.DDM.refreshCache(this.groups);
347 // private - override to prevent hiding
348 b4EndDrag: function(e) {
351 // private - override to prevent moving
352 endDrag : function(e){
353 this.onEndDrag(this.dragData, e);
357 onEndDrag : function(data, e){
360 // private - pin to cursor
361 autoOffset : function(x, y) {
362 this.setDelta(-12, -20);