2 * @class Ext.core.Element
6 var ELEMENT = Ext.core.Element,
11 POSITION = "position",
13 RELATIVE = "relative",
17 Ext.override(Ext.core.Element, {
19 * 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).
20 * @return {Number} The X position of the element
23 return ELEMENT.getX(this.dom);
27 * 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).
28 * @return {Number} The Y position of the element
31 return ELEMENT.getY(this.dom);
35 * 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).
36 * @return {Array} The XY position of the element
39 return ELEMENT.getXY(this.dom);
43 * 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.
44 * @param {Mixed} element The element to get the offsets from.
45 * @return {Array} The XY page offsets (e.g. [100, -200])
47 getOffsetsTo : function(el){
49 e = Ext.fly(el, '_internal').getXY();
50 return [o[0]-e[0],o[1]-e[1]];
54 * 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).
55 * @param {Number} The X position of the element
56 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
57 * @return {Ext.core.Element} this
59 setX : function(x, animate){
60 return this.setXY([x, this.getY()], animate);
64 * 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).
65 * @param {Number} The Y position of the element
66 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
67 * @return {Ext.core.Element} this
69 setY : function(y, animate){
70 return this.setXY([this.getX(), y], animate);
74 * Sets the element's left position directly using CSS style (instead of {@link #setX}).
75 * @param {String} left The left CSS property value
76 * @return {Ext.core.Element} this
78 setLeft : function(left){
79 this.setStyle(LEFT, this.addUnits(left));
84 * Sets the element's top position directly using CSS style (instead of {@link #setY}).
85 * @param {String} top The top CSS property value
86 * @return {Ext.core.Element} this
88 setTop : function(top){
89 this.setStyle(TOP, this.addUnits(top));
94 * Sets the element's CSS right style.
95 * @param {String} right The right CSS property value
96 * @return {Ext.core.Element} this
98 setRight : function(right){
99 this.setStyle(RIGHT, this.addUnits(right));
104 * Sets the element's CSS bottom style.
105 * @param {String} bottom The bottom CSS property value
106 * @return {Ext.core.Element} this
108 setBottom : function(bottom){
109 this.setStyle(BOTTOM, this.addUnits(bottom));
114 * Sets the position of the element in page coordinates, regardless of how the element is positioned.
115 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
116 * @param {Array} pos Contains X & Y [x, y] values for new position (coordinates are page-based)
117 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
118 * @return {Ext.core.Element} this
120 setXY: function(pos, animate) {
122 if (!animate || !me.anim) {
123 ELEMENT.setXY(me.dom, pos);
126 if (!Ext.isObject(animate)) {
129 me.animate(Ext.applyIf({ to: { x: pos[0], y: pos[1] } }, animate));
135 * Sets the position of the element in page coordinates, regardless of how the element is positioned.
136 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
137 * @param {Number} x X value for new position (coordinates are page-based)
138 * @param {Number} y Y value for new position (coordinates are page-based)
139 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
140 * @return {Ext.core.Element} this
142 setLocation : function(x, y, animate){
143 return this.setXY([x, y], animate);
147 * Sets the position of the element in page coordinates, regardless of how the element is positioned.
148 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
149 * @param {Number} x X value for new position (coordinates are page-based)
150 * @param {Number} y Y value for new position (coordinates are page-based)
151 * @param {Boolean/Object} animate (optional) True for the default animation, or a standard Element animation config object
152 * @return {Ext.core.Element} this
154 moveTo : function(x, y, animate){
155 return this.setXY([x, y], animate);
159 * Gets the left X coordinate
160 * @param {Boolean} local True to get the local css position instead of page coordinate
163 getLeft : function(local){
164 return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
168 * Gets the right X coordinate of the element (element X position + element width)
169 * @param {Boolean} local True to get the local css position instead of page coordinate
172 getRight : function(local){
174 return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
178 * Gets the top Y coordinate
179 * @param {Boolean} local True to get the local css position instead of page coordinate
182 getTop : function(local) {
183 return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
187 * Gets the bottom Y coordinate of the element (element Y position + element height)
188 * @param {Boolean} local True to get the local css position instead of page coordinate
191 getBottom : function(local){
193 return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
197 * Initializes positioning on this element. If a desired position is not passed, it will make the
198 * the element positioned relative IF it is not already positioned.
199 * @param {String} pos (optional) Positioning to use "relative", "absolute" or "fixed"
200 * @param {Number} zIndex (optional) The zIndex to apply
201 * @param {Number} x (optional) Set the page X position
202 * @param {Number} y (optional) Set the page Y position
204 position : function(pos, zIndex, x, y) {
207 if (!pos && me.isStyle(POSITION, STATIC)){
208 me.setStyle(POSITION, RELATIVE);
210 me.setStyle(POSITION, pos);
213 me.setStyle(ZINDEX, zIndex);
216 me.setXY([x || false, y || false]);
221 * Clear positioning back to the default when the document was loaded
222 * @param {String} value (optional) The value to use for the left,right,top,bottom, defaults to '' (empty string). You could use 'auto'.
223 * @return {Ext.core.Element} this
225 clearPositioning : function(value){
239 * Gets an object with all CSS positioning properties. Useful along with setPostioning to get
240 * snapshot before performing an update and then restoring the element.
243 getPositioning : function(){
244 var l = this.getStyle(LEFT);
245 var t = this.getStyle(TOP);
247 "position" : this.getStyle(POSITION),
249 "right" : l ? "" : this.getStyle(RIGHT),
251 "bottom" : t ? "" : this.getStyle(BOTTOM),
252 "z-index" : this.getStyle(ZINDEX)
257 * Set positioning with an object returned by getPositioning().
258 * @param {Object} posCfg
259 * @return {Ext.core.Element} this
261 setPositioning : function(pc){
263 style = me.dom.style;
267 if(pc.right == AUTO){
270 if(pc.bottom == AUTO){
278 * Translates the passed page coordinates into left/top css values for this element
279 * @param {Number/Array} x The page x or an array containing [x, y]
280 * @param {Number} y (optional) The page y, required if x is not an array
281 * @return {Object} An object with left and top properties. e.g. {left: (value), top: (value)}
283 translatePoints: function(x, y) {
284 if (Ext.isArray(x)) {
289 relative = me.isStyle(POSITION, RELATIVE),
291 left = parseInt(me.getStyle(LEFT), 10),
292 top = parseInt(me.getStyle(TOP), 10);
294 if (!Ext.isNumber(left)) {
295 left = relative ? 0 : me.dom.offsetLeft;
297 if (!Ext.isNumber(top)) {
298 top = relative ? 0 : me.dom.offsetTop;
300 left = (Ext.isNumber(x)) ? x - o[0] + left : undefined;
301 top = (Ext.isNumber(y)) ? y - o[1] + top : undefined;
309 * Sets the element's box. Use getBox() on another element to get a box obj. If animate is true then width, height, x and y will be animated concurrently.
310 * @param {Object} box The box to fill {x, y, width, height}
311 * @param {Boolean} adjust (optional) Whether to adjust for box-model issues automatically
312 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
313 * @return {Ext.core.Element} this
315 setBox: function(box, adjust, animate) {
319 if ((adjust && !me.autoBoxAdjust) && !me.isBorderBox()) {
320 w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
321 h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
323 me.setBounds(box.x, box.y, w, h, animate);
328 * Return an object defining the area of this Element which can be passed to {@link #setBox} to
329 * set another Element's size/location to match this element.
330 * @param {Boolean} contentBox (optional) If true a box for the content of the element is returned.
331 * @param {Boolean} local (optional) If true the element's left and top are returned instead of page x/y.
332 * @return {Object} box An object in the format<pre><code>
334 x: <Element's X position>,
335 y: <Element's Y position>,
336 width: <Element's width>,
337 height: <Element's height>,
338 bottom: <Element's lower bound>,
339 right: <Element's rightmost bound>
342 * The returned object may also be addressed as an Array where index 0 contains the X position
343 * and index 1 contains the Y position. So the result may also be used for {@link #setXY}
345 getBox: function(contentBox, local) {
350 getBorderWidth = me.getBorderWidth,
351 getPadding = me.getPadding,
352 l, r, t, b, w, h, bx;
356 left = parseInt(me.getStyle("left"), 10) || 0;
357 top = parseInt(me.getStyle("top"), 10) || 0;
372 l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
373 r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
374 t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
375 b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
385 bx.right = bx.x + bx.width;
386 bx.bottom = bx.y + bx.height;
391 * Move this element relative to its current position.
392 * @param {String} direction Possible values are: "l" (or "left"), "r" (or "right"), "t" (or "top", or "up"), "b" (or "bottom", or "down").
393 * @param {Number} distance How far to move the element in pixels
394 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
395 * @return {Ext.core.Element} this
397 move: function(direction, distance, animate) {
402 left = [x - distance, y],
403 right = [x + distance, y],
404 top = [x, y - distance],
405 bottom = [x, y + distance],
419 direction = direction.toLowerCase();
420 me.moveTo(hash[direction][0], hash[direction][1], animate);
424 * Quick set left and top adding default units
425 * @param {String} left The left CSS property value
426 * @param {String} top The top CSS property value
427 * @return {Ext.core.Element} this
429 setLeftTop: function(left, top) {
431 style = me.dom.style;
432 style.left = me.addUnits(left);
433 style.top = me.addUnits(top);
438 * Returns the region of this element.
439 * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
440 * @return {Region} A Ext.util.Region containing "top, left, bottom, right" member data.
442 getRegion: function() {
443 return this.getPageBox(true);
447 * Returns the <b>content</b> region of this element. That is the region within the borders and padding.
448 * @return {Region} A Ext.util.Region containing "top, left, bottom, right" member data.
450 getViewRegion: function() {
452 isBody = me.dom === document.body,
453 scroll, pos, top, left, width, height;
455 // For the body we want to do some special logic
457 scroll = me.getScroll();
460 width = Ext.core.Element.getViewportWidth();
461 height = Ext.core.Element.getViewportHeight();
465 left = pos[0] + me.getBorderWidth('l') + me.getPadding('l');
466 top = pos[1] + me.getBorderWidth('t') + me.getPadding('t');
467 width = me.getWidth(true);
468 height = me.getHeight(true);
471 return Ext.create('Ext.util.Region', top, left + width, top + height, left);
475 * Return an object defining the area of this Element which can be passed to {@link #setBox} to
476 * set another Element's size/location to match this element.
477 * @param {Boolean} asRegion(optional) If true an Ext.util.Region will be returned
478 * @return {Object} box An object in the format<pre><code>
480 x: <Element's X position>,
481 y: <Element's Y position>,
482 width: <Element's width>,
483 height: <Element's height>,
484 bottom: <Element's lower bound>,
485 right: <Element's rightmost bound>
488 * The returned object may also be addressed as an Array where index 0 contains the X position
489 * and index 1 contains the Y position. So the result may also be used for {@link #setXY}
491 getPageBox : function(getRegion) {
494 isDoc = el === document.body,
495 w = isDoc ? Ext.core.Element.getViewWidth() : el.offsetWidth,
496 h = isDoc ? Ext.core.Element.getViewHeight() : el.offsetHeight,
504 return Ext.create('Ext.util.Region', t, r, b, l);
519 * Sets the element's position and size in one shot. If animation is true then width, height, x and y will be animated concurrently.
520 * @param {Number} x X value for new position (coordinates are page-based)
521 * @param {Number} y Y value for new position (coordinates are page-based)
522 * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
523 * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels)</li>
524 * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
526 * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
527 * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels)</li>
528 * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
530 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
531 * @return {Ext.core.Element} this
533 setBounds: function(x, y, width, height, animate) {
535 if (!animate || !me.anim) {
536 me.setSize(width, height);
537 me.setLocation(x, y);
539 if (!Ext.isObject(animate)) {
542 me.animate(Ext.applyIf({
546 width: me.adjustWidth(width),
547 height: me.adjustHeight(height)
555 * Sets the element's position and size the specified region. If animation is true then width, height, x and y will be animated concurrently.
556 * @param {Ext.util.Region} region The region to fill
557 * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
558 * @return {Ext.core.Element} this
560 setRegion: function(region, animate) {
561 return this.setBounds(region.left, region.top, region.right - region.left, region.bottom - region.top, animate);