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