Upgrade to ExtJS 3.2.0 - Released 03/30/2010
[extjs.git] / src / ext-core / src / core / Element.position.js
1 /*!
2  * Ext JS Library 3.2.0
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**
8  * @class Ext.Element
9  */
10 (function(){
11 var D = Ext.lib.Dom,
12         LEFT = "left",
13         RIGHT = "right",
14         TOP = "top",
15         BOTTOM = "bottom",
16         POSITION = "position",
17         STATIC = "static",
18         RELATIVE = "relative",
19         AUTO = "auto",
20         ZINDEX = "z-index";
21
22 Ext.Element.addMethods({
23         /**
24       * Gets the current X position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
25       * @return {Number} The X position of the element
26       */
27     getX : function(){
28         return D.getX(this.dom);
29     },
30
31     /**
32       * Gets the current Y position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
33       * @return {Number} The Y position of the element
34       */
35     getY : function(){
36         return D.getY(this.dom);
37     },
38
39     /**
40       * Gets the current position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
41       * @return {Array} The XY position of the element
42       */
43     getXY : function(){
44         return D.getXY(this.dom);
45     },
46
47     /**
48       * Returns the offsets of this element from the passed element. Both element must be part of the DOM tree and not have display:none to have page coordinates.
49       * @param {Mixed} element The element to get the offsets from.
50       * @return {Array} The XY page offsets (e.g. [100, -200])
51       */
52     getOffsetsTo : function(el){
53         var o = this.getXY(),
54                 e = Ext.fly(el, '_internal').getXY();
55         return [o[0]-e[0],o[1]-e[1]];
56     },
57
58     /**
59      * Sets the X position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
60      * @param {Number} The X position of the element
61      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
62      * @return {Ext.Element} this
63      */
64     setX : function(x, animate){            
65             return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
66     },
67
68     /**
69      * Sets the Y position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
70      * @param {Number} The Y position of the element
71      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
72      * @return {Ext.Element} this
73      */
74     setY : function(y, animate){            
75             return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
76     },
77
78     /**
79      * Sets the element's left position directly using CSS style (instead of {@link #setX}).
80      * @param {String} left The left CSS property value
81      * @return {Ext.Element} this
82      */
83     setLeft : function(left){
84         this.setStyle(LEFT, this.addUnits(left));
85         return this;
86     },
87
88     /**
89      * Sets the element's top position directly using CSS style (instead of {@link #setY}).
90      * @param {String} top The top CSS property value
91      * @return {Ext.Element} this
92      */
93     setTop : function(top){
94         this.setStyle(TOP, this.addUnits(top));
95         return this;
96     },
97
98     /**
99      * Sets the element's CSS right style.
100      * @param {String} right The right CSS property value
101      * @return {Ext.Element} this
102      */
103     setRight : function(right){
104         this.setStyle(RIGHT, this.addUnits(right));
105         return this;
106     },
107
108     /**
109      * Sets the element's CSS bottom style.
110      * @param {String} bottom The bottom CSS property value
111      * @return {Ext.Element} this
112      */
113     setBottom : function(bottom){
114         this.setStyle(BOTTOM, this.addUnits(bottom));
115         return this;
116     },
117
118     /**
119      * Sets the position of the element in page coordinates, regardless of how the element is positioned.
120      * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
121      * @param {Array} pos Contains X & Y [x, y] values for new position (coordinates are page-based)
122      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
123      * @return {Ext.Element} this
124      */
125     setXY : function(pos, animate){
126             var me = this;
127         if(!animate || !me.anim){
128             D.setXY(me.dom, pos);
129         }else{
130             me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
131         }
132         return me;
133     },
134
135     /**
136      * Sets the position of the element in page coordinates, regardless of how the element is positioned.
137      * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
138      * @param {Number} x X value for new position (coordinates are page-based)
139      * @param {Number} y Y value for new position (coordinates are page-based)
140      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
141      * @return {Ext.Element} this
142      */
143     setLocation : function(x, y, animate){
144         return this.setXY([x, y], this.animTest(arguments, animate, 2));
145     },
146
147     /**
148      * Sets the position of the element in page coordinates, regardless of how the element is positioned.
149      * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
150      * @param {Number} x X value for new position (coordinates are page-based)
151      * @param {Number} y Y value for new position (coordinates are page-based)
152      * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
153      * @return {Ext.Element} this
154      */
155     moveTo : function(x, y, animate){
156         return this.setXY([x, y], this.animTest(arguments, animate, 2));        
157     },    
158     
159     /**
160      * Gets the left X coordinate
161      * @param {Boolean} local True to get the local css position instead of page coordinate
162      * @return {Number}
163      */
164     getLeft : function(local){
165             return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
166     },
167
168     /**
169      * Gets the right X coordinate of the element (element X position + element width)
170      * @param {Boolean} local True to get the local css position instead of page coordinate
171      * @return {Number}
172      */
173     getRight : function(local){
174             var me = this;
175             return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
176     },
177
178     /**
179      * Gets the top Y coordinate
180      * @param {Boolean} local True to get the local css position instead of page coordinate
181      * @return {Number}
182      */
183     getTop : function(local) {
184             return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
185     },
186
187     /**
188      * Gets the bottom Y coordinate of the element (element Y position + element height)
189      * @param {Boolean} local True to get the local css position instead of page coordinate
190      * @return {Number}
191      */
192     getBottom : function(local){
193             var me = this;
194             return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
195     },
196
197     /**
198     * Initializes positioning on this element. If a desired position is not passed, it will make the
199     * the element positioned relative IF it is not already positioned.
200     * @param {String} pos (optional) Positioning to use "relative", "absolute" or "fixed"
201     * @param {Number} zIndex (optional) The zIndex to apply
202     * @param {Number} x (optional) Set the page X position
203     * @param {Number} y (optional) Set the page Y position
204     */
205     position : function(pos, zIndex, x, y){
206             var me = this;
207             
208         if(!pos && me.isStyle(POSITION, STATIC)){           
209             me.setStyle(POSITION, RELATIVE);           
210         } else if(pos) {
211             me.setStyle(POSITION, pos);
212         }
213         if(zIndex){
214             me.setStyle(ZINDEX, zIndex);
215         }
216         if(x || y) me.setXY([x || false, y || false]);
217     },
218
219     /**
220     * Clear positioning back to the default when the document was loaded
221     * @param {String} value (optional) The value to use for the left,right,top,bottom, defaults to '' (empty string). You could use 'auto'.
222     * @return {Ext.Element} this
223      */
224     clearPositioning : function(value){
225         value = value || '';
226         this.setStyle({
227             left : value,
228             right : value,
229             top : value,
230             bottom : value,
231             "z-index" : "",
232             position : STATIC
233         });
234         return this;
235     },
236
237     /**
238     * Gets an object with all CSS positioning properties. Useful along with setPostioning to get
239     * snapshot before performing an update and then restoring the element.
240     * @return {Object}
241     */
242     getPositioning : function(){
243         var l = this.getStyle(LEFT);
244         var t = this.getStyle(TOP);
245         return {
246             "position" : this.getStyle(POSITION),
247             "left" : l,
248             "right" : l ? "" : this.getStyle(RIGHT),
249             "top" : t,
250             "bottom" : t ? "" : this.getStyle(BOTTOM),
251             "z-index" : this.getStyle(ZINDEX)
252         };
253     },
254     
255     /**
256     * Set positioning with an object returned by getPositioning().
257     * @param {Object} posCfg
258     * @return {Ext.Element} this
259      */
260     setPositioning : function(pc){
261             var me = this,
262                 style = me.dom.style;
263                 
264         me.setStyle(pc);
265         
266         if(pc.right == AUTO){
267             style.right = "";
268         }
269         if(pc.bottom == AUTO){
270             style.bottom = "";
271         }
272         
273         return me;
274     },    
275         
276     /**
277      * Translates the passed page coordinates into left/top css values for this element
278      * @param {Number/Array} x The page x or an array containing [x, y]
279      * @param {Number} y (optional) The page y, required if x is not an array
280      * @return {Object} An object with left and top properties. e.g. {left: (value), top: (value)}
281      */
282     translatePoints : function(x, y){                
283             y = isNaN(x[1]) ? y : x[1];
284         x = isNaN(x[0]) ? x : x[0];
285         var me = this,
286                 relative = me.isStyle(POSITION, RELATIVE),
287                 o = me.getXY(),
288                 l = parseInt(me.getStyle(LEFT), 10),
289                 t = parseInt(me.getStyle(TOP), 10);
290         
291         l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
292         t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);        
293
294         return {left: (x - o[0] + l), top: (y - o[1] + t)}; 
295     },
296     
297     animTest : function(args, animate, i) {
298         return !!animate && this.preanim ? this.preanim(args, i) : false;
299     }
300 });
301 })();