Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / DragDrop.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js">/*
19  * This is a derivative of the similarly named class in the YUI Library.
20  * The original license:
21  * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
22  * Code licensed under the BSD License:
23  * http://developer.yahoo.net/yui/license.txt
24  */
25
26
27 <span id='Ext-dd-DragDrop-method-constructor'><span id='Ext-dd-DragDrop'>/**
28 </span></span> * @class Ext.dd.DragDrop
29  * Defines the interface and base operation of items that that can be
30  * dragged or can be drop targets.  It was designed to be extended, overriding
31  * the event handlers for startDrag, onDrag, onDragOver and onDragOut.
32  * Up to three html elements can be associated with a DragDrop instance:
33  * &lt;ul&gt;
34  * &lt;li&gt;linked element: the element that is passed into the constructor.
35  * This is the element which defines the boundaries for interaction with
36  * other DragDrop objects.&lt;/li&gt;
37  * &lt;li&gt;handle element(s): The drag operation only occurs if the element that
38  * was clicked matches a handle element.  By default this is the linked
39  * element, but there are times that you will want only a portion of the
40  * linked element to initiate the drag operation, and the setHandleElId()
41  * method provides a way to define this.&lt;/li&gt;
42  * &lt;li&gt;drag element: this represents the element that would be moved along
43  * with the cursor during a drag operation.  By default, this is the linked
44  * element itself as in {@link Ext.dd.DD}.  setDragElId() lets you define
45  * a separate element that would be moved, as in {@link Ext.dd.DDProxy}.
46  * &lt;/li&gt;
47  * &lt;/ul&gt;
48  * This class should not be instantiated until the onload event to ensure that
49  * the associated elements are available.
50  * The following would define a DragDrop obj that would interact with any
51  * other DragDrop obj in the &quot;group1&quot; group:
52  * &lt;pre&gt;
53  *  dd = new Ext.dd.DragDrop(&quot;div1&quot;, &quot;group1&quot;);
54  * &lt;/pre&gt;
55  * Since none of the event handlers have been implemented, nothing would
56  * actually happen if you were to run the code above.  Normally you would
57  * override this class or one of the default implementations, but you can
58  * also override the methods you want on an instance of the class...
59  * &lt;pre&gt;
60  *  dd.onDragDrop = function(e, id) {
61  *  &amp;nbsp;&amp;nbsp;alert(&quot;dd was dropped on &quot; + id);
62  *  }
63  * &lt;/pre&gt;
64  * @constructor
65  * @param {String} id of the element that is linked to this instance
66  * @param {String} sGroup the group of related DragDrop objects
67  * @param {object} config an object containing configurable attributes
68  *                Valid properties for DragDrop:
69  *                    padding, isTarget, maintainOffset, primaryButtonOnly
70  */
71
72 Ext.define('Ext.dd.DragDrop', {
73     requires: ['Ext.dd.DragDropManager'],
74     constructor: function(id, sGroup, config) {
75         if(id) {
76             this.init(id, sGroup, config);
77         }
78     },
79     
80 <span id='Ext-dd-DragDrop-property-ignoreSelf'>    /**
81 </span>     * Set to false to enable a DragDrop object to fire drag events while dragging
82      * over its own Element. Defaults to true - DragDrop objects do not by default
83      * fire drag events to themselves.
84      * @property ignoreSelf
85      * @type Boolean
86      */
87
88 <span id='Ext-dd-DragDrop-property-id'>    /**
89 </span>     * The id of the element associated with this object.  This is what we
90      * refer to as the &quot;linked element&quot; because the size and position of
91      * this element is used to determine when the drag and drop objects have
92      * interacted.
93      * @property id
94      * @type String
95      */
96     id: null,
97
98 <span id='Ext-dd-DragDrop-property-config'>    /**
99 </span>     * Configuration attributes passed into the constructor
100      * @property config
101      * @type object
102      */
103     config: null,
104
105 <span id='Ext-dd-DragDrop-property-dragElId'>    /**
106 </span>     * The id of the element that will be dragged.  By default this is same
107      * as the linked element, but could be changed to another element. Ex:
108      * Ext.dd.DDProxy
109      * @property dragElId
110      * @type String
111      * @private
112      */
113     dragElId: null,
114
115 <span id='Ext-dd-DragDrop-property-handleElId'>    /**
116 </span>     * The ID of the element that initiates the drag operation.  By default
117      * this is the linked element, but could be changed to be a child of this
118      * element.  This lets us do things like only starting the drag when the
119      * header element within the linked html element is clicked.
120      * @property handleElId
121      * @type String
122      * @private
123      */
124     handleElId: null,
125
126 <span id='Ext-dd-DragDrop-property-invalidHandleTypes'>    /**
127 </span>     * An object who's property names identify HTML tags to be considered invalid as drag handles.
128      * A non-null property value identifies the tag as invalid. Defaults to the 
129      * following value which prevents drag operations from being initiated by &amp;lt;a&gt; elements:&lt;pre&gt;&lt;code&gt;
130 {
131     A: &quot;A&quot;
132 }&lt;/code&gt;&lt;/pre&gt;
133      * @property invalidHandleTypes
134      * @type Object
135      */
136     invalidHandleTypes: null,
137
138 <span id='Ext-dd-DragDrop-property-invalidHandleIds'>    /**
139 </span>     * An object who's property names identify the IDs of elements to be considered invalid as drag handles.
140      * A non-null property value identifies the ID as invalid. For example, to prevent
141      * dragging from being initiated on element ID &quot;foo&quot;, use:&lt;pre&gt;&lt;code&gt;
142 {
143     foo: true
144 }&lt;/code&gt;&lt;/pre&gt;
145      * @property invalidHandleIds
146      * @type Object
147      */
148     invalidHandleIds: null,
149
150 <span id='Ext-dd-DragDrop-property-invalidHandleClasses'>    /**
151 </span>     * An Array of CSS class names for elements to be considered in valid as drag handles.
152      * @property invalidHandleClasses
153      * @type Array
154      */
155     invalidHandleClasses: null,
156
157 <span id='Ext-dd-DragDrop-property-startPageX'>    /**
158 </span>     * The linked element's absolute X position at the time the drag was
159      * started
160      * @property startPageX
161      * @type int
162      * @private
163      */
164     startPageX: 0,
165
166 <span id='Ext-dd-DragDrop-property-startPageY'>    /**
167 </span>     * The linked element's absolute X position at the time the drag was
168      * started
169      * @property startPageY
170      * @type int
171      * @private
172      */
173     startPageY: 0,
174
175 <span id='Ext-dd-DragDrop-property-groups'>    /**
176 </span>     * The group defines a logical collection of DragDrop objects that are
177      * related.  Instances only get events when interacting with other
178      * DragDrop object in the same group.  This lets us define multiple
179      * groups using a single DragDrop subclass if we want.
180      * @property groups
181      * @type object An object in the format {'group1':true, 'group2':true}
182      */
183     groups: null,
184
185 <span id='Ext-dd-DragDrop-property-locked'>    /**
186 </span>     * Individual drag/drop instances can be locked.  This will prevent
187      * onmousedown start drag.
188      * @property locked
189      * @type boolean
190      * @private
191      */
192     locked: false,
193
194 <span id='Ext-dd-DragDrop-method-lock'>    /**
195 </span>     * Lock this instance
196      * @method lock
197      */
198     lock: function() {
199         this.locked = true;
200     },
201
202 <span id='Ext-dd-DragDrop-property-moveOnly'>    /**
203 </span>     * When set to true, other DD objects in cooperating DDGroups do not receive
204      * notification events when this DD object is dragged over them. Defaults to false.
205      * @property moveOnly
206      * @type boolean
207      */
208     moveOnly: false,
209
210 <span id='Ext-dd-DragDrop-method-unlock'>    /**
211 </span>     * Unlock this instace
212      * @method unlock
213      */
214     unlock: function() {
215         this.locked = false;
216     },
217
218 <span id='Ext-dd-DragDrop-property-isTarget'>    /**
219 </span>     * By default, all instances can be a drop target.  This can be disabled by
220      * setting isTarget to false.
221      * @property isTarget
222      * @type boolean
223      */
224     isTarget: true,
225
226 <span id='Ext-dd-DragDrop-property-padding'>    /**
227 </span>     * The padding configured for this drag and drop object for calculating
228      * the drop zone intersection with this object.
229      * An array containing the 4 padding values: [top, right, bottom, left]
230      * @property {[int]} padding
231      */
232     padding: null,
233
234 <span id='Ext-dd-DragDrop-property-_domRef'>    /**
235 </span>     * Cached reference to the linked element
236      * @property _domRef
237      * @private
238      */
239     _domRef: null,
240
241 <span id='Ext-dd-DragDrop-property-__ygDragDrop'>    /**
242 </span>     * Internal typeof flag
243      * @property __ygDragDrop
244      * @private
245      */
246     __ygDragDrop: true,
247
248 <span id='Ext-dd-DragDrop-property-constrainX'>    /**
249 </span>     * Set to true when horizontal contraints are applied
250      * @property constrainX
251      * @type boolean
252      * @private
253      */
254     constrainX: false,
255
256 <span id='Ext-dd-DragDrop-property-constrainY'>    /**
257 </span>     * Set to true when vertical contraints are applied
258      * @property constrainY
259      * @type boolean
260      * @private
261      */
262     constrainY: false,
263
264 <span id='Ext-dd-DragDrop-property-minX'>    /**
265 </span>     * The left constraint
266      * @property minX
267      * @type int
268      * @private
269      */
270     minX: 0,
271
272 <span id='Ext-dd-DragDrop-property-maxX'>    /**
273 </span>     * The right constraint
274      * @property maxX
275      * @type int
276      * @private
277      */
278     maxX: 0,
279
280 <span id='Ext-dd-DragDrop-property-minY'>    /**
281 </span>     * The up constraint
282      * @property minY
283      * @type int
284      * @private
285      */
286     minY: 0,
287
288 <span id='Ext-dd-DragDrop-property-maxY'>    /**
289 </span>     * The down constraint
290      * @property maxY
291      * @type int
292      * @private
293      */
294     maxY: 0,
295
296 <span id='Ext-dd-DragDrop-property-maintainOffset'>    /**
297 </span>     * Maintain offsets when we resetconstraints.  Set to true when you want
298      * the position of the element relative to its parent to stay the same
299      * when the page changes
300      *
301      * @property maintainOffset
302      * @type boolean
303      */
304     maintainOffset: false,
305
306 <span id='Ext-dd-DragDrop-property-xTicks'>    /**
307 </span>     * Array of pixel locations the element will snap to if we specified a
308      * horizontal graduation/interval.  This array is generated automatically
309      * when you define a tick interval.
310      * @property {[int]} xTicks
311      */
312     xTicks: null,
313
314 <span id='Ext-dd-DragDrop-property-yTicks'>    /**
315 </span>     * Array of pixel locations the element will snap to if we specified a
316      * vertical graduation/interval.  This array is generated automatically
317      * when you define a tick interval.
318      * @property {[int]} yTicks
319      */
320     yTicks: null,
321
322 <span id='Ext-dd-DragDrop-property-primaryButtonOnly'>    /**
323 </span>     * By default the drag and drop instance will only respond to the primary
324      * button click (left button for a right-handed mouse).  Set to true to
325      * allow drag and drop to start with any mouse click that is propogated
326      * by the browser
327      * @property primaryButtonOnly
328      * @type boolean
329      */
330     primaryButtonOnly: true,
331
332 <span id='Ext-dd-DragDrop-property-available'>    /**
333 </span>     * The available property is false until the linked dom element is accessible.
334      * @property available
335      * @type boolean
336      */
337     available: false,
338
339 <span id='Ext-dd-DragDrop-property-hasOuterHandles'>    /**
340 </span>     * By default, drags can only be initiated if the mousedown occurs in the
341      * region the linked element is.  This is done in part to work around a
342      * bug in some browsers that mis-report the mousedown if the previous
343      * mouseup happened outside of the window.  This property is set to true
344      * if outer handles are defined.
345      *
346      * @property hasOuterHandles
347      * @type boolean
348      * @default false
349      */
350     hasOuterHandles: false,
351
352 <span id='Ext-dd-DragDrop-method-b4StartDrag'>    /**
353 </span>     * Code that executes immediately before the startDrag event
354      * @method b4StartDrag
355      * @private
356      */
357     b4StartDrag: function(x, y) { },
358
359 <span id='Ext-dd-DragDrop-method-startDrag'>    /**
360 </span>     * Abstract method called after a drag/drop object is clicked
361      * and the drag or mousedown time thresholds have beeen met.
362      * @method startDrag
363      * @param {int} X click location
364      * @param {int} Y click location
365      */
366     startDrag: function(x, y) { /* override this */ },
367
368 <span id='Ext-dd-DragDrop-method-b4Drag'>    /**
369 </span>     * Code that executes immediately before the onDrag event
370      * @method b4Drag
371      * @private
372      */
373     b4Drag: function(e) { },
374
375 <span id='Ext-dd-DragDrop-method-onDrag'>    /**
376 </span>     * Abstract method called during the onMouseMove event while dragging an
377      * object.
378      * @method onDrag
379      * @param {Event} e the mousemove event
380      */
381     onDrag: function(e) { /* override this */ },
382
383 <span id='Ext-dd-DragDrop-method-onDragEnter'>    /**
384 </span>     * Abstract method called when this element fist begins hovering over
385      * another DragDrop obj
386      * @method onDragEnter
387      * @param {Event} e the mousemove event
388      * @param {String|DragDrop[]} id In POINT mode, the element
389      * id this is hovering over.  In INTERSECT mode, an array of one or more
390      * dragdrop items being hovered over.
391      */
392     onDragEnter: function(e, id) { /* override this */ },
393
394 <span id='Ext-dd-DragDrop-method-b4DragOver'>    /**
395 </span>     * Code that executes immediately before the onDragOver event
396      * @method b4DragOver
397      * @private
398      */
399     b4DragOver: function(e) { },
400
401 <span id='Ext-dd-DragDrop-method-onDragOver'>    /**
402 </span>     * Abstract method called when this element is hovering over another
403      * DragDrop obj
404      * @method onDragOver
405      * @param {Event} e the mousemove event
406      * @param {String|DragDrop[]} id In POINT mode, the element
407      * id this is hovering over.  In INTERSECT mode, an array of dd items
408      * being hovered over.
409      */
410     onDragOver: function(e, id) { /* override this */ },
411
412 <span id='Ext-dd-DragDrop-method-b4DragOut'>    /**
413 </span>     * Code that executes immediately before the onDragOut event
414      * @method b4DragOut
415      * @private
416      */
417     b4DragOut: function(e) { },
418
419 <span id='Ext-dd-DragDrop-method-onDragOut'>    /**
420 </span>     * Abstract method called when we are no longer hovering over an element
421      * @method onDragOut
422      * @param {Event} e the mousemove event
423      * @param {String|DragDrop[]} id In POINT mode, the element
424      * id this was hovering over.  In INTERSECT mode, an array of dd items
425      * that the mouse is no longer over.
426      */
427     onDragOut: function(e, id) { /* override this */ },
428
429 <span id='Ext-dd-DragDrop-method-b4DragDrop'>    /**
430 </span>     * Code that executes immediately before the onDragDrop event
431      * @method b4DragDrop
432      * @private
433      */
434     b4DragDrop: function(e) { },
435
436 <span id='Ext-dd-DragDrop-method-onDragDrop'>    /**
437 </span>     * Abstract method called when this item is dropped on another DragDrop
438      * obj
439      * @method onDragDrop
440      * @param {Event} e the mouseup event
441      * @param {String|DragDrop[]} id In POINT mode, the element
442      * id this was dropped on.  In INTERSECT mode, an array of dd items this
443      * was dropped on.
444      */
445     onDragDrop: function(e, id) { /* override this */ },
446
447 <span id='Ext-dd-DragDrop-method-onInvalidDrop'>    /**
448 </span>     * Abstract method called when this item is dropped on an area with no
449      * drop target
450      * @method onInvalidDrop
451      * @param {Event} e the mouseup event
452      */
453     onInvalidDrop: function(e) { /* override this */ },
454
455 <span id='Ext-dd-DragDrop-method-b4EndDrag'>    /**
456 </span>     * Code that executes immediately before the endDrag event
457      * @method b4EndDrag
458      * @private
459      */
460     b4EndDrag: function(e) { },
461
462 <span id='Ext-dd-DragDrop-method-endDrag'>    /**
463 </span>     * Fired when we are done dragging the object
464      * @method endDrag
465      * @param {Event} e the mouseup event
466      */
467     endDrag: function(e) { /* override this */ },
468
469 <span id='Ext-dd-DragDrop-method-b4MouseDown'>    /**
470 </span>     * Code executed immediately before the onMouseDown event
471      * @method b4MouseDown
472      * @param {Event} e the mousedown event
473      * @private
474      */
475     b4MouseDown: function(e) {  },
476
477 <span id='Ext-dd-DragDrop-method-onMouseDown'>    /**
478 </span>     * Event handler that fires when a drag/drop obj gets a mousedown
479      * @method onMouseDown
480      * @param {Event} e the mousedown event
481      */
482     onMouseDown: function(e) { /* override this */ },
483
484 <span id='Ext-dd-DragDrop-method-onMouseUp'>    /**
485 </span>     * Event handler that fires when a drag/drop obj gets a mouseup
486      * @method onMouseUp
487      * @param {Event} e the mouseup event
488      */
489     onMouseUp: function(e) { /* override this */ },
490
491 <span id='Ext-dd-DragDrop-method-onAvailable'>    /**
492 </span>     * Override the onAvailable method to do what is needed after the initial
493      * position was determined.
494      * @method onAvailable
495      */
496     onAvailable: function () {
497     },
498
499 <span id='Ext-dd-DragDrop-property-defaultPadding'>    /**
500 </span>     * Provides default constraint padding to &quot;constrainTo&quot; elements (defaults to {left: 0, right:0, top:0, bottom:0}).
501      * @type Object
502      */
503     defaultPadding: {
504         left: 0,
505         right: 0,
506         top: 0,
507         bottom: 0
508     },
509
510 <span id='Ext-dd-DragDrop-method-constrainTo'>    /**
511 </span>     * Initializes the drag drop object's constraints to restrict movement to a certain element.
512  *
513  * Usage:
514  &lt;pre&gt;&lt;code&gt;
515  var dd = new Ext.dd.DDProxy(&quot;dragDiv1&quot;, &quot;proxytest&quot;,
516                 { dragElId: &quot;existingProxyDiv&quot; });
517  dd.startDrag = function(){
518      this.constrainTo(&quot;parent-id&quot;);
519  };
520  &lt;/code&gt;&lt;/pre&gt;
521  * Or you can initalize it using the {@link Ext.core.Element} object:
522  &lt;pre&gt;&lt;code&gt;
523  Ext.get(&quot;dragDiv1&quot;).initDDProxy(&quot;proxytest&quot;, {dragElId: &quot;existingProxyDiv&quot;}, {
524      startDrag : function(){
525          this.constrainTo(&quot;parent-id&quot;);
526      }
527  });
528  &lt;/code&gt;&lt;/pre&gt;
529      * @param {Mixed} constrainTo The element to constrain to.
530      * @param {Object/Number} pad (optional) Pad provides a way to specify &quot;padding&quot; of the constraints,
531      * and can be either a number for symmetrical padding (4 would be equal to {left:4, right:4, top:4, bottom:4}) or
532      * an object containing the sides to pad. For example: {right:10, bottom:10}
533      * @param {Boolean} inContent (optional) Constrain the draggable in the content box of the element (inside padding and borders)
534      */
535     constrainTo : function(constrainTo, pad, inContent){
536         if(Ext.isNumber(pad)){
537             pad = {left: pad, right:pad, top:pad, bottom:pad};
538         }
539         pad = pad || this.defaultPadding;
540         var b = Ext.get(this.getEl()).getBox(),
541             ce = Ext.get(constrainTo),
542             s = ce.getScroll(),
543             c, 
544             cd = ce.dom;
545         if(cd == document.body){
546             c = { x: s.left, y: s.top, width: Ext.core.Element.getViewWidth(), height: Ext.core.Element.getViewHeight()};
547         }else{
548             var xy = ce.getXY();
549             c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
550         }
551
552
553         var topSpace = b.y - c.y,
554             leftSpace = b.x - c.x;
555
556         this.resetConstraints();
557         this.setXConstraint(leftSpace - (pad.left||0), // left
558                 c.width - leftSpace - b.width - (pad.right||0), //right
559                                 this.xTickSize
560         );
561         this.setYConstraint(topSpace - (pad.top||0), //top
562                 c.height - topSpace - b.height - (pad.bottom||0), //bottom
563                                 this.yTickSize
564         );
565     },
566
567 <span id='Ext-dd-DragDrop-method-getEl'>    /**
568 </span>     * Returns a reference to the linked element
569      * @method getEl
570      * @return {HTMLElement} the html element
571      */
572     getEl: function() {
573         if (!this._domRef) {
574             this._domRef = Ext.getDom(this.id);
575         }
576
577         return this._domRef;
578     },
579
580 <span id='Ext-dd-DragDrop-method-getDragEl'>    /**
581 </span>     * Returns a reference to the actual element to drag.  By default this is
582      * the same as the html element, but it can be assigned to another
583      * element. An example of this can be found in Ext.dd.DDProxy
584      * @method getDragEl
585      * @return {HTMLElement} the html element
586      */
587     getDragEl: function() {
588         return Ext.getDom(this.dragElId);
589     },
590
591 <span id='Ext-dd-DragDrop-method-init'>    /**
592 </span>     * Sets up the DragDrop object.  Must be called in the constructor of any
593      * Ext.dd.DragDrop subclass
594      * @method init
595      * @param id the id of the linked element
596      * @param {String} sGroup the group of related items
597      * @param {object} config configuration attributes
598      */
599     init: function(id, sGroup, config) {
600         this.initTarget(id, sGroup, config);
601         Ext.EventManager.on(this.id, &quot;mousedown&quot;, this.handleMouseDown, this);
602         // Ext.EventManager.on(this.id, &quot;selectstart&quot;, Event.preventDefault);
603     },
604
605 <span id='Ext-dd-DragDrop-method-initTarget'>    /**
606 </span>     * Initializes Targeting functionality only... the object does not
607      * get a mousedown handler.
608      * @method initTarget
609      * @param id the id of the linked element
610      * @param {String} sGroup the group of related items
611      * @param {object} config configuration attributes
612      */
613     initTarget: function(id, sGroup, config) {
614
615         // configuration attributes
616         this.config = config || {};
617
618         // create a local reference to the drag and drop manager
619         this.DDMInstance = Ext.dd.DragDropManager;
620         // initialize the groups array
621         this.groups = {};
622
623         // assume that we have an element reference instead of an id if the
624         // parameter is not a string
625         if (typeof id !== &quot;string&quot;) {
626             id = Ext.id(id);
627         }
628
629         // set the id
630         this.id = id;
631
632         // add to an interaction group
633         this.addToGroup((sGroup) ? sGroup : &quot;default&quot;);
634
635         // We don't want to register this as the handle with the manager
636         // so we just set the id rather than calling the setter.
637         this.handleElId = id;
638
639         // the linked element is the element that gets dragged by default
640         this.setDragElId(id);
641
642         // by default, clicked anchors will not start drag operations.
643         this.invalidHandleTypes = { A: &quot;A&quot; };
644         this.invalidHandleIds = {};
645         this.invalidHandleClasses = [];
646
647         this.applyConfig();
648
649         this.handleOnAvailable();
650     },
651
652 <span id='Ext-dd-DragDrop-method-applyConfig'>    /**
653 </span>     * Applies the configuration parameters that were passed into the constructor.
654      * This is supposed to happen at each level through the inheritance chain.  So
655      * a DDProxy implentation will execute apply config on DDProxy, DD, and
656      * DragDrop in order to get all of the parameters that are available in
657      * each object.
658      * @method applyConfig
659      */
660     applyConfig: function() {
661
662         // configurable properties:
663         //    padding, isTarget, maintainOffset, primaryButtonOnly
664         this.padding           = this.config.padding || [0, 0, 0, 0];
665         this.isTarget          = (this.config.isTarget !== false);
666         this.maintainOffset    = (this.config.maintainOffset);
667         this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
668
669     },
670
671 <span id='Ext-dd-DragDrop-method-handleOnAvailable'>    /**
672 </span>     * Executed when the linked element is available
673      * @method handleOnAvailable
674      * @private
675      */
676     handleOnAvailable: function() {
677         this.available = true;
678         this.resetConstraints();
679         this.onAvailable();
680     },
681
682 <span id='Ext-dd-DragDrop-method-setPadding'>     /**
683 </span>     * Configures the padding for the target zone in px.  Effectively expands
684      * (or reduces) the virtual object size for targeting calculations.
685      * Supports css-style shorthand; if only one parameter is passed, all sides
686      * will have that padding, and if only two are passed, the top and bottom
687      * will have the first param, the left and right the second.
688      * @method setPadding
689      * @param {int} iTop    Top pad
690      * @param {int} iRight  Right pad
691      * @param {int} iBot    Bot pad
692      * @param {int} iLeft   Left pad
693      */
694     setPadding: function(iTop, iRight, iBot, iLeft) {
695         // this.padding = [iLeft, iRight, iTop, iBot];
696         if (!iRight &amp;&amp; 0 !== iRight) {
697             this.padding = [iTop, iTop, iTop, iTop];
698         } else if (!iBot &amp;&amp; 0 !== iBot) {
699             this.padding = [iTop, iRight, iTop, iRight];
700         } else {
701             this.padding = [iTop, iRight, iBot, iLeft];
702         }
703     },
704
705 <span id='Ext-dd-DragDrop-method-setInitPosition'>    /**
706 </span>     * Stores the initial placement of the linked element.
707      * @method setInitPosition
708      * @param {int} diffX   the X offset, default 0
709      * @param {int} diffY   the Y offset, default 0
710      */
711     setInitPosition: function(diffX, diffY) {
712         var el = this.getEl();
713
714         if (!this.DDMInstance.verifyEl(el)) {
715             return;
716         }
717
718         var dx = diffX || 0;
719         var dy = diffY || 0;
720
721         var p = Ext.core.Element.getXY( el );
722
723         this.initPageX = p[0] - dx;
724         this.initPageY = p[1] - dy;
725
726         this.lastPageX = p[0];
727         this.lastPageY = p[1];
728
729         this.setStartPosition(p);
730     },
731
732 <span id='Ext-dd-DragDrop-method-setStartPosition'>    /**
733 </span>     * Sets the start position of the element.  This is set when the obj
734      * is initialized, the reset when a drag is started.
735      * @method setStartPosition
736      * @param pos current position (from previous lookup)
737      * @private
738      */
739     setStartPosition: function(pos) {
740         var p = pos || Ext.core.Element.getXY( this.getEl() );
741         this.deltaSetXY = null;
742
743         this.startPageX = p[0];
744         this.startPageY = p[1];
745     },
746
747 <span id='Ext-dd-DragDrop-method-addToGroup'>    /**
748 </span>     * Add this instance to a group of related drag/drop objects.  All
749      * instances belong to at least one group, and can belong to as many
750      * groups as needed.
751      * @method addToGroup
752      * @param sGroup {string} the name of the group
753      */
754     addToGroup: function(sGroup) {
755         this.groups[sGroup] = true;
756         this.DDMInstance.regDragDrop(this, sGroup);
757     },
758
759 <span id='Ext-dd-DragDrop-method-removeFromGroup'>    /**
760 </span>     * Remove's this instance from the supplied interaction group
761      * @method removeFromGroup
762      * @param {string}  sGroup  The group to drop
763      */
764     removeFromGroup: function(sGroup) {
765         if (this.groups[sGroup]) {
766             delete this.groups[sGroup];
767         }
768
769         this.DDMInstance.removeDDFromGroup(this, sGroup);
770     },
771
772 <span id='Ext-dd-DragDrop-method-setDragElId'>    /**
773 </span>     * Allows you to specify that an element other than the linked element
774      * will be moved with the cursor during a drag
775      * @method setDragElId
776      * @param id {string} the id of the element that will be used to initiate the drag
777      */
778     setDragElId: function(id) {
779         this.dragElId = id;
780     },
781
782 <span id='Ext-dd-DragDrop-method-setHandleElId'>    /**
783 </span>     * Allows you to specify a child of the linked element that should be
784      * used to initiate the drag operation.  An example of this would be if
785      * you have a content div with text and links.  Clicking anywhere in the
786      * content area would normally start the drag operation.  Use this method
787      * to specify that an element inside of the content div is the element
788      * that starts the drag operation.
789      * @method setHandleElId
790      * @param id {string} the id of the element that will be used to
791      * initiate the drag.
792      */
793     setHandleElId: function(id) {
794         if (typeof id !== &quot;string&quot;) {
795             id = Ext.id(id);
796         }
797         this.handleElId = id;
798         this.DDMInstance.regHandle(this.id, id);
799     },
800
801 <span id='Ext-dd-DragDrop-method-setOuterHandleElId'>    /**
802 </span>     * Allows you to set an element outside of the linked element as a drag
803      * handle
804      * @method setOuterHandleElId
805      * @param id the id of the element that will be used to initiate the drag
806      */
807     setOuterHandleElId: function(id) {
808         if (typeof id !== &quot;string&quot;) {
809             id = Ext.id(id);
810         }
811         Ext.EventManager.on(id, &quot;mousedown&quot;, this.handleMouseDown, this);
812         this.setHandleElId(id);
813
814         this.hasOuterHandles = true;
815     },
816
817 <span id='Ext-dd-DragDrop-method-unreg'>    /**
818 </span>     * Remove all drag and drop hooks for this element
819      * @method unreg
820      */
821     unreg: function() {
822         Ext.EventManager.un(this.id, &quot;mousedown&quot;, this.handleMouseDown, this);
823         this._domRef = null;
824         this.DDMInstance._remove(this);
825     },
826
827     destroy : function(){
828         this.unreg();
829     },
830
831 <span id='Ext-dd-DragDrop-method-isLocked'>    /**
832 </span>     * Returns true if this instance is locked, or the drag drop mgr is locked
833      * (meaning that all drag/drop is disabled on the page.)
834      * @method isLocked
835      * @return {boolean} true if this obj or all drag/drop is locked, else
836      * false
837      */
838     isLocked: function() {
839         return (this.DDMInstance.isLocked() || this.locked);
840     },
841
842 <span id='Ext-dd-DragDrop-method-handleMouseDown'>    /**
843 </span>     * Fired when this object is clicked
844      * @method handleMouseDown
845      * @param {Event} e
846      * @param {Ext.dd.DragDrop} oDD the clicked dd object (this dd obj)
847      * @private
848      */
849     handleMouseDown: function(e, oDD){
850         if (this.primaryButtonOnly &amp;&amp; e.button != 0) {
851             return;
852         }
853
854         if (this.isLocked()) {
855             return;
856         }
857
858         this.DDMInstance.refreshCache(this.groups);
859
860         var pt = e.getPoint();
861         if (!this.hasOuterHandles &amp;&amp; !this.DDMInstance.isOverTarget(pt, this) )  {
862         } else {
863             if (this.clickValidator(e)) {
864                 // set the initial element position
865                 this.setStartPosition();
866                 this.b4MouseDown(e);
867                 this.onMouseDown(e);
868
869                 this.DDMInstance.handleMouseDown(e, this);
870
871                 this.DDMInstance.stopEvent(e);
872             } else {
873
874
875             }
876         }
877     },
878
879     clickValidator: function(e) {
880         var target = e.getTarget();
881         return ( this.isValidHandleChild(target) &amp;&amp;
882                     (this.id == this.handleElId ||
883                         this.DDMInstance.handleWasClicked(target, this.id)) );
884     },
885
886 <span id='Ext-dd-DragDrop-method-addInvalidHandleType'>    /**
887 </span>     * Allows you to specify a tag name that should not start a drag operation
888      * when clicked.  This is designed to facilitate embedding links within a
889      * drag handle that do something other than start the drag.
890      * @method addInvalidHandleType
891      * @param {string} tagName the type of element to exclude
892      */
893     addInvalidHandleType: function(tagName) {
894         var type = tagName.toUpperCase();
895         this.invalidHandleTypes[type] = type;
896     },
897
898 <span id='Ext-dd-DragDrop-method-addInvalidHandleId'>    /**
899 </span>     * Lets you to specify an element id for a child of a drag handle
900      * that should not initiate a drag
901      * @method addInvalidHandleId
902      * @param {string} id the element id of the element you wish to ignore
903      */
904     addInvalidHandleId: function(id) {
905         if (typeof id !== &quot;string&quot;) {
906             id = Ext.id(id);
907         }
908         this.invalidHandleIds[id] = id;
909     },
910
911 <span id='Ext-dd-DragDrop-method-addInvalidHandleClass'>    /**
912 </span>     * Lets you specify a css class of elements that will not initiate a drag
913      * @method addInvalidHandleClass
914      * @param {string} cssClass the class of the elements you wish to ignore
915      */
916     addInvalidHandleClass: function(cssClass) {
917         this.invalidHandleClasses.push(cssClass);
918     },
919
920 <span id='Ext-dd-DragDrop-method-removeInvalidHandleType'>    /**
921 </span>     * Unsets an excluded tag name set by addInvalidHandleType
922      * @method removeInvalidHandleType
923      * @param {string} tagName the type of element to unexclude
924      */
925     removeInvalidHandleType: function(tagName) {
926         var type = tagName.toUpperCase();
927         // this.invalidHandleTypes[type] = null;
928         delete this.invalidHandleTypes[type];
929     },
930
931 <span id='Ext-dd-DragDrop-method-removeInvalidHandleId'>    /**
932 </span>     * Unsets an invalid handle id
933      * @method removeInvalidHandleId
934      * @param {string} id the id of the element to re-enable
935      */
936     removeInvalidHandleId: function(id) {
937         if (typeof id !== &quot;string&quot;) {
938             id = Ext.id(id);
939         }
940         delete this.invalidHandleIds[id];
941     },
942
943 <span id='Ext-dd-DragDrop-method-removeInvalidHandleClass'>    /**
944 </span>     * Unsets an invalid css class
945      * @method removeInvalidHandleClass
946      * @param {string} cssClass the class of the element(s) you wish to
947      * re-enable
948      */
949     removeInvalidHandleClass: function(cssClass) {
950         for (var i=0, len=this.invalidHandleClasses.length; i&lt;len; ++i) {
951             if (this.invalidHandleClasses[i] == cssClass) {
952                 delete this.invalidHandleClasses[i];
953             }
954         }
955     },
956
957 <span id='Ext-dd-DragDrop-method-isValidHandleChild'>    /**
958 </span>     * Checks the tag exclusion list to see if this click should be ignored
959      * @method isValidHandleChild
960      * @param {HTMLElement} node the HTMLElement to evaluate
961      * @return {boolean} true if this is a valid tag type, false if not
962      */
963     isValidHandleChild: function(node) {
964
965         var valid = true;
966         // var n = (node.nodeName == &quot;#text&quot;) ? node.parentNode : node;
967         var nodeName;
968         try {
969             nodeName = node.nodeName.toUpperCase();
970         } catch(e) {
971             nodeName = node.nodeName;
972         }
973         valid = valid &amp;&amp; !this.invalidHandleTypes[nodeName];
974         valid = valid &amp;&amp; !this.invalidHandleIds[node.id];
975
976         for (var i=0, len=this.invalidHandleClasses.length; valid &amp;&amp; i&lt;len; ++i) {
977             valid = !Ext.fly(node).hasCls(this.invalidHandleClasses[i]);
978         }
979
980
981         return valid;
982
983     },
984
985 <span id='Ext-dd-DragDrop-method-setXTicks'>    /**
986 </span>     * Create the array of horizontal tick marks if an interval was specified
987      * in setXConstraint().
988      * @method setXTicks
989      * @private
990      */
991     setXTicks: function(iStartX, iTickSize) {
992         this.xTicks = [];
993         this.xTickSize = iTickSize;
994
995         var tickMap = {};
996
997         for (var i = this.initPageX; i &gt;= this.minX; i = i - iTickSize) {
998             if (!tickMap[i]) {
999                 this.xTicks[this.xTicks.length] = i;
1000                 tickMap[i] = true;
1001             }
1002         }
1003
1004         for (i = this.initPageX; i &lt;= this.maxX; i = i + iTickSize) {
1005             if (!tickMap[i]) {
1006                 this.xTicks[this.xTicks.length] = i;
1007                 tickMap[i] = true;
1008             }
1009         }
1010
1011         Ext.Array.sort(this.xTicks, this.DDMInstance.numericSort);
1012     },
1013
1014 <span id='Ext-dd-DragDrop-method-setYTicks'>    /**
1015 </span>     * Create the array of vertical tick marks if an interval was specified in
1016      * setYConstraint().
1017      * @method setYTicks
1018      * @private
1019      */
1020     setYTicks: function(iStartY, iTickSize) {
1021         this.yTicks = [];
1022         this.yTickSize = iTickSize;
1023
1024         var tickMap = {};
1025
1026         for (var i = this.initPageY; i &gt;= this.minY; i = i - iTickSize) {
1027             if (!tickMap[i]) {
1028                 this.yTicks[this.yTicks.length] = i;
1029                 tickMap[i] = true;
1030             }
1031         }
1032
1033         for (i = this.initPageY; i &lt;= this.maxY; i = i + iTickSize) {
1034             if (!tickMap[i]) {
1035                 this.yTicks[this.yTicks.length] = i;
1036                 tickMap[i] = true;
1037             }
1038         }
1039
1040         Ext.Array.sort(this.yTicks, this.DDMInstance.numericSort);
1041     },
1042
1043 <span id='Ext-dd-DragDrop-method-setXConstraint'>    /**
1044 </span>     * By default, the element can be dragged any place on the screen.  Use
1045      * this method to limit the horizontal travel of the element.  Pass in
1046      * 0,0 for the parameters if you want to lock the drag to the y axis.
1047      * @method setXConstraint
1048      * @param {int} iLeft the number of pixels the element can move to the left
1049      * @param {int} iRight the number of pixels the element can move to the
1050      * right
1051      * @param {int} iTickSize optional parameter for specifying that the
1052      * element
1053      * should move iTickSize pixels at a time.
1054      */
1055     setXConstraint: function(iLeft, iRight, iTickSize) {
1056         this.leftConstraint = iLeft;
1057         this.rightConstraint = iRight;
1058
1059         this.minX = this.initPageX - iLeft;
1060         this.maxX = this.initPageX + iRight;
1061         if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
1062
1063         this.constrainX = true;
1064     },
1065
1066 <span id='Ext-dd-DragDrop-method-clearConstraints'>    /**
1067 </span>     * Clears any constraints applied to this instance.  Also clears ticks
1068      * since they can't exist independent of a constraint at this time.
1069      * @method clearConstraints
1070      */
1071     clearConstraints: function() {
1072         this.constrainX = false;
1073         this.constrainY = false;
1074         this.clearTicks();
1075     },
1076
1077 <span id='Ext-dd-DragDrop-method-clearTicks'>    /**
1078 </span>     * Clears any tick interval defined for this instance
1079      * @method clearTicks
1080      */
1081     clearTicks: function() {
1082         this.xTicks = null;
1083         this.yTicks = null;
1084         this.xTickSize = 0;
1085         this.yTickSize = 0;
1086     },
1087
1088 <span id='Ext-dd-DragDrop-method-setYConstraint'>    /**
1089 </span>     * By default, the element can be dragged any place on the screen.  Set
1090      * this to limit the vertical travel of the element.  Pass in 0,0 for the
1091      * parameters if you want to lock the drag to the x axis.
1092      * @method setYConstraint
1093      * @param {int} iUp the number of pixels the element can move up
1094      * @param {int} iDown the number of pixels the element can move down
1095      * @param {int} iTickSize optional parameter for specifying that the
1096      * element should move iTickSize pixels at a time.
1097      */
1098     setYConstraint: function(iUp, iDown, iTickSize) {
1099         this.topConstraint = iUp;
1100         this.bottomConstraint = iDown;
1101
1102         this.minY = this.initPageY - iUp;
1103         this.maxY = this.initPageY + iDown;
1104         if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
1105
1106         this.constrainY = true;
1107
1108     },
1109
1110 <span id='Ext-dd-DragDrop-method-resetConstraints'>    /**
1111 </span>     * resetConstraints must be called if you manually reposition a dd element.
1112      * @method resetConstraints
1113      * @param {boolean} maintainOffset
1114      */
1115     resetConstraints: function() {
1116         // Maintain offsets if necessary
1117         if (this.initPageX || this.initPageX === 0) {
1118             // figure out how much this thing has moved
1119             var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
1120             var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
1121
1122             this.setInitPosition(dx, dy);
1123
1124         // This is the first time we have detected the element's position
1125         } else {
1126             this.setInitPosition();
1127         }
1128
1129         if (this.constrainX) {
1130             this.setXConstraint( this.leftConstraint,
1131                                  this.rightConstraint,
1132                                  this.xTickSize        );
1133         }
1134
1135         if (this.constrainY) {
1136             this.setYConstraint( this.topConstraint,
1137                                  this.bottomConstraint,
1138                                  this.yTickSize         );
1139         }
1140     },
1141
1142 <span id='Ext-dd-DragDrop-method-getTick'>    /**
1143 </span>     * Normally the drag element is moved pixel by pixel, but we can specify
1144      * that it move a number of pixels at a time.  This method resolves the
1145      * location when we have it set up like this.
1146      * @method getTick
1147      * @param {int} val where we want to place the object
1148      * @param {int[]} tickArray sorted array of valid points
1149      * @return {int} the closest tick
1150      * @private
1151      */
1152     getTick: function(val, tickArray) {
1153         if (!tickArray) {
1154             // If tick interval is not defined, it is effectively 1 pixel,
1155             // so we return the value passed to us.
1156             return val;
1157         } else if (tickArray[0] &gt;= val) {
1158             // The value is lower than the first tick, so we return the first
1159             // tick.
1160             return tickArray[0];
1161         } else {
1162             for (var i=0, len=tickArray.length; i&lt;len; ++i) {
1163                 var next = i + 1;
1164                 if (tickArray[next] &amp;&amp; tickArray[next] &gt;= val) {
1165                     var diff1 = val - tickArray[i];
1166                     var diff2 = tickArray[next] - val;
1167                     return (diff2 &gt; diff1) ? tickArray[i] : tickArray[next];
1168                 }
1169             }
1170
1171             // The value is larger than the last tick, so we return the last
1172             // tick.
1173             return tickArray[tickArray.length - 1];
1174         }
1175     },
1176
1177 <span id='Ext-dd-DragDrop-method-toString'>    /**
1178 </span>     * toString method
1179      * @method toString
1180      * @return {string} string representation of the dd obj
1181      */
1182     toString: function() {
1183         return (&quot;DragDrop &quot; + this.id);
1184     }
1185
1186 });</pre>
1187 </body>
1188 </html>