Upgrade to ExtJS 3.0.3 - Released 10/11/2009
[extjs.git] / docs / source / Element.alignment.html
1 <html>
2 <head>
3   <title>The source code</title>
4     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
5     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
6 </head>
7 <body  onload="prettyPrint();">
8     <pre class="prettyprint lang-js">/*!
9  * Ext JS Library 3.0.3
10  * Copyright(c) 2006-2009 Ext JS, LLC
11  * licensing@extjs.com
12  * http://www.extjs.com/license
13  */
14 /**\r
15  * @class Ext.Element\r
16  */\r
17 Ext.Element.addMethods({\r
18     <div id="method-Ext.Element-getAnchorXY"></div>/**\r
19      * Gets the x,y coordinates specified by the anchor position on the element.\r
20      * @param {String} anchor (optional) The specified anchor position (defaults to "c").  See {@link #alignTo}\r
21      * for details on supported anchor positions.\r
22      * @param {Boolean} local (optional) True to get the local (element top/left-relative) anchor position instead\r
23      * of page coordinates\r
24      * @param {Object} size (optional) An object containing the size to use for calculating anchor position\r
25      * {width: (target width), height: (target height)} (defaults to the element's current size)\r
26      * @return {Array} [x, y] An array containing the element's x and y coordinates\r
27      */\r
28     getAnchorXY : function(anchor, local, s){\r
29         //Passing a different size is useful for pre-calculating anchors,\r
30         //especially for anchored animations that change the el size.\r
31                 anchor = (anchor || "tl").toLowerCase();\r
32         s = s || {};\r
33         \r
34         var me = this,        \r
35                 vp = me.dom == document.body || me.dom == document,\r
36                 w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),\r
37                 h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),                              \r
38                 xy,             \r
39                 r = Math.round,\r
40                 o = me.getXY(),\r
41                 scroll = me.getScroll(),\r
42                 extraX = vp ? scroll.left : !local ? o[0] : 0,\r
43                 extraY = vp ? scroll.top : !local ? o[1] : 0,\r
44                 hash = {\r
45                         c  : [r(w * 0.5), r(h * 0.5)],\r
46                         t  : [r(w * 0.5), 0],\r
47                         l  : [0, r(h * 0.5)],\r
48                         r  : [w, r(h * 0.5)],\r
49                         b  : [r(w * 0.5), h],\r
50                         tl : [0, 0],    \r
51                         bl : [0, h],\r
52                         br : [w, h],\r
53                         tr : [w, 0]\r
54                 };\r
55         \r
56         xy = hash[anchor];      \r
57         return [xy[0] + extraX, xy[1] + extraY]; \r
58     },\r
59 \r
60     <div id="method-Ext.Element-anchorTo"></div>/**\r
61      * Anchors an element to another element and realigns it when the window is resized.\r
62      * @param {Mixed} element The element to align to.\r
63      * @param {String} position The position to align to.\r
64      * @param {Array} offsets (optional) Offset the positioning by [x, y]\r
65      * @param {Boolean/Object} animate (optional) True for the default animation or a standard Element animation config object\r
66      * @param {Boolean/Number} monitorScroll (optional) True to monitor body scroll and reposition. If this parameter\r
67      * is a number, it is used as the buffer delay (defaults to 50ms).\r
68      * @param {Function} callback The function to call after the animation finishes\r
69      * @return {Ext.Element} this\r
70      */\r
71     anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){        \r
72             var me = this,\r
73             dom = me.dom;\r
74             \r
75             function action(){\r
76             Ext.fly(dom).alignTo(el, alignment, offsets, animate);\r
77             Ext.callback(callback, Ext.fly(dom));\r
78         }\r
79         \r
80         Ext.EventManager.onWindowResize(action, me);\r
81         \r
82         if(!Ext.isEmpty(monitorScroll)){\r
83             Ext.EventManager.on(window, 'scroll', action, me,\r
84                 {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});\r
85         }\r
86         action.call(me); // align immediately\r
87         return me;\r
88     },\r
89 \r
90     <div id="method-Ext.Element-getAlignToXY"></div>/**\r
91      * Gets the x,y coordinates to align this element with another element. See {@link #alignTo} for more info on the\r
92      * supported position values.\r
93      * @param {Mixed} element The element to align to.\r
94      * @param {String} position The position to align to.\r
95      * @param {Array} offsets (optional) Offset the positioning by [x, y]\r
96      * @return {Array} [x, y]\r
97      */\r
98     getAlignToXY : function(el, p, o){      \r
99         el = Ext.get(el);\r
100         \r
101         if(!el || !el.dom){\r
102             throw "Element.alignToXY with an element that doesn't exist";\r
103         }\r
104         \r
105         o = o || [0,0];\r
106         p = (p == "?" ? "tl-bl?" : (!/-/.test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();       \r
107                 \r
108         var me = this,\r
109                 d = me.dom,\r
110                 a1,\r
111                 a2,\r
112                 x,\r
113                 y,\r
114                 //constrain the aligned el to viewport if necessary\r
115                 w,\r
116                 h,\r
117                 r,\r
118                 dw = Ext.lib.Dom.getViewWidth() -10, // 10px of margin for ie\r
119                 dh = Ext.lib.Dom.getViewHeight()-10, // 10px of margin for ie\r
120                 p1y,\r
121                 p1x,            \r
122                 p2y,\r
123                 p2x,\r
124                 swapY,\r
125                 swapX,\r
126                 doc = document,\r
127                 docElement = doc.documentElement,\r
128                 docBody = doc.body,\r
129                 scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,\r
130                 scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,\r
131                 c = false, //constrain to viewport\r
132                 p1 = "", \r
133                 p2 = "",\r
134                 m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);\r
135         \r
136         if(!m){\r
137            throw "Element.alignTo with an invalid alignment " + p;\r
138         }\r
139         \r
140         p1 = m[1]; \r
141         p2 = m[2]; \r
142         c = !!m[3];\r
143 \r
144         //Subtract the aligned el's internal xy from the target's offset xy\r
145         //plus custom offset to get the aligned el's new offset xy\r
146         a1 = me.getAnchorXY(p1, true);\r
147         a2 = el.getAnchorXY(p2, false);\r
148 \r
149         x = a2[0] - a1[0] + o[0];\r
150         y = a2[1] - a1[1] + o[1];\r
151 \r
152         if(c){    \r
153                w = me.getWidth();\r
154            h = me.getHeight();\r
155            r = el.getRegion();       \r
156            //If we are at a viewport boundary and the aligned el is anchored on a target border that is\r
157            //perpendicular to the vp border, allow the aligned el to slide on that border,\r
158            //otherwise swap the aligned el to the opposite border of the target.\r
159            p1y = p1.charAt(0);\r
160            p1x = p1.charAt(p1.length-1);\r
161            p2y = p2.charAt(0);\r
162            p2x = p2.charAt(p2.length-1);\r
163            swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));\r
164            swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));          \r
165            \r
166 \r
167            if (x + w > dw + scrollX) {\r
168                 x = swapX ? r.left-w : dw+scrollX-w;\r
169            }\r
170            if (x < scrollX) {\r
171                x = swapX ? r.right : scrollX;\r
172            }\r
173            if (y + h > dh + scrollY) {\r
174                 y = swapY ? r.top-h : dh+scrollY-h;\r
175             }\r
176            if (y < scrollY){\r
177                y = swapY ? r.bottom : scrollY;\r
178            }\r
179         }\r
180         return [x,y];\r
181     },\r
182 \r
183     <div id="method-Ext.Element-alignTo"></div>/**\r
184      * Aligns this element with another element relative to the specified anchor points. If the other element is the\r
185      * document it aligns it to the viewport.\r
186      * The position parameter is optional, and can be specified in any one of the following formats:\r
187      * <ul>\r
188      *   <li><b>Blank</b>: Defaults to aligning the element's top-left corner to the target's bottom-left corner ("tl-bl").</li>\r
189      *   <li><b>One anchor (deprecated)</b>: The passed anchor position is used as the target element's anchor point.\r
190      *       The element being aligned will position its top-left corner (tl) to that point.  <i>This method has been\r
191      *       deprecated in favor of the newer two anchor syntax below</i>.</li>\r
192      *   <li><b>Two anchors</b>: If two values from the table below are passed separated by a dash, the first value is used as the\r
193      *       element's anchor point, and the second value is used as the target's anchor point.</li>\r
194      * </ul>\r
195      * In addition to the anchor points, the position parameter also supports the "?" character.  If "?" is passed at the end of\r
196      * the position string, the element will attempt to align as specified, but the position will be adjusted to constrain to\r
197      * the viewport if necessary.  Note that the element being aligned might be swapped to align to a different position than\r
198      * that specified in order to enforce the viewport constraints.\r
199      * Following are all of the supported anchor positions:\r
200 <pre>\r
201 Value  Description\r
202 -----  -----------------------------\r
203 tl     The top left corner (default)\r
204 t      The center of the top edge\r
205 tr     The top right corner\r
206 l      The center of the left edge\r
207 c      In the center of the element\r
208 r      The center of the right edge\r
209 bl     The bottom left corner\r
210 b      The center of the bottom edge\r
211 br     The bottom right corner\r
212 </pre>\r
213 Example Usage:\r
214 <pre><code>\r
215 // align el to other-el using the default positioning ("tl-bl", non-constrained)\r
216 el.alignTo("other-el");\r
217 \r
218 // align the top left corner of el with the top right corner of other-el (constrained to viewport)\r
219 el.alignTo("other-el", "tr?");\r
220 \r
221 // align the bottom right corner of el with the center left edge of other-el\r
222 el.alignTo("other-el", "br-l?");\r
223 \r
224 // align the center of el with the bottom left corner of other-el and\r
225 // adjust the x position by -6 pixels (and the y position by 0)\r
226 el.alignTo("other-el", "c-bl", [-6, 0]);\r
227 </code></pre>\r
228      * @param {Mixed} element The element to align to.\r
229      * @param {String} position The position to align to.\r
230      * @param {Array} offsets (optional) Offset the positioning by [x, y]\r
231      * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
232      * @return {Ext.Element} this\r
233      */\r
234     alignTo : function(element, position, offsets, animate){\r
235             var me = this;\r
236         return me.setXY(me.getAlignToXY(element, position, offsets),\r
237                                 me.preanim && !!animate ? me.preanim(arguments, 3) : false);\r
238     },\r
239     \r
240     // private ==>  used outside of core\r
241     adjustForConstraints : function(xy, parent, offsets){\r
242         return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;\r
243     },\r
244 \r
245     // private ==>  used outside of core\r
246     getConstrainToXY : function(el, local, offsets, proposedXY){   \r
247             var os = {top:0, left:0, bottom:0, right: 0};\r
248 \r
249         return function(el, local, offsets, proposedXY){\r
250             el = Ext.get(el);\r
251             offsets = offsets ? Ext.applyIf(offsets, os) : os;\r
252 \r
253             var vw, vh, vx = 0, vy = 0;\r
254             if(el.dom == document.body || el.dom == document){\r
255                 vw =Ext.lib.Dom.getViewWidth();\r
256                 vh = Ext.lib.Dom.getViewHeight();\r
257             }else{\r
258                 vw = el.dom.clientWidth;\r
259                 vh = el.dom.clientHeight;\r
260                 if(!local){\r
261                     var vxy = el.getXY();\r
262                     vx = vxy[0];\r
263                     vy = vxy[1];\r
264                 }\r
265             }\r
266 \r
267             var s = el.getScroll();\r
268 \r
269             vx += offsets.left + s.left;\r
270             vy += offsets.top + s.top;\r
271 \r
272             vw -= offsets.right;\r
273             vh -= offsets.bottom;\r
274 \r
275             var vr = vx+vw;\r
276             var vb = vy+vh;\r
277 \r
278             var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);\r
279             var x = xy[0], y = xy[1];\r
280             var w = this.dom.offsetWidth, h = this.dom.offsetHeight;\r
281 \r
282             // only move it if it needs it\r
283             var moved = false;\r
284 \r
285             // first validate right/bottom\r
286             if((x + w) > vr){\r
287                 x = vr - w;\r
288                 moved = true;\r
289             }\r
290             if((y + h) > vb){\r
291                 y = vb - h;\r
292                 moved = true;\r
293             }\r
294             // then make sure top/left isn't negative\r
295             if(x < vx){\r
296                 x = vx;\r
297                 moved = true;\r
298             }\r
299             if(y < vy){\r
300                 y = vy;\r
301                 moved = true;\r
302             }\r
303             return moved ? [x, y] : false;\r
304         };\r
305     }(),\r
306             \r
307             \r
308                 \r
309 //         el = Ext.get(el);\r
310 //         offsets = Ext.applyIf(offsets || {}, {top : 0, left : 0, bottom : 0, right : 0});\r
311 \r
312 //         var  me = this,\r
313 //              doc = document,\r
314 //              s = el.getScroll(),\r
315 //              vxy = el.getXY(),\r
316 //              vx = offsets.left + s.left, \r
317 //              vy = offsets.top + s.top,               \r
318 //              vw = -offsets.right, \r
319 //              vh = -offsets.bottom, \r
320 //              vr,\r
321 //              vb,\r
322 //              xy = proposedXY || (!local ? me.getXY() : [me.getLeft(true), me.getTop(true)]),\r
323 //              x = xy[0],\r
324 //              y = xy[1],\r
325 //              w = me.dom.offsetWidth, h = me.dom.offsetHeight,\r
326 //              moved = false; // only move it if it needs it\r
327 //       \r
328 //              \r
329 //         if(el.dom == doc.body || el.dom == doc){\r
330 //             vw += Ext.lib.Dom.getViewWidth();\r
331 //             vh += Ext.lib.Dom.getViewHeight();\r
332 //         }else{\r
333 //             vw += el.dom.clientWidth;\r
334 //             vh += el.dom.clientHeight;\r
335 //             if(!local){                    \r
336 //                 vx += vxy[0];\r
337 //                 vy += vxy[1];\r
338 //             }\r
339 //         }\r
340 \r
341 //         // first validate right/bottom\r
342 //         if(x + w > vx + vw){\r
343 //             x = vx + vw - w;\r
344 //             moved = true;\r
345 //         }\r
346 //         if(y + h > vy + vh){\r
347 //             y = vy + vh - h;\r
348 //             moved = true;\r
349 //         }\r
350 //         // then make sure top/left isn't negative\r
351 //         if(x < vx){\r
352 //             x = vx;\r
353 //             moved = true;\r
354 //         }\r
355 //         if(y < vy){\r
356 //             y = vy;\r
357 //             moved = true;\r
358 //         }\r
359 //         return moved ? [x, y] : false;\r
360 //    },\r
361     \r
362     <div id="method-Ext.Element-getCenterXY"></div>/**\r
363     * Calculates the x, y to center this element on the screen\r
364     * @return {Array} The x, y values [x, y]\r
365     */\r
366     getCenterXY : function(){\r
367         return this.getAlignToXY(document, 'c-c');\r
368     },\r
369 \r
370     <div id="method-Ext.Element-center"></div>/**\r
371     * Centers the Element in either the viewport, or another Element.\r
372     * @param {Mixed} centerIn (optional) The element in which to center the element.\r
373     */\r
374     center : function(centerIn){\r
375         return this.alignTo(centerIn || document, 'c-c');        \r
376     }    \r
377 });\r
378 </pre>
379 </body>
380 </html>