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