2 Copyright (c) 2011, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.com/yui/license.html
8 * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
9 * @namespace YAHOO.widget
10 * @requires yahoo, dom, element, event
14 var Dom = YAHOO.util.Dom,
15 Event = YAHOO.util.Event,
21 * @extends YAHOO.util.Element
22 * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
23 * @param {String/HTMLElement} el The element to make contain a layout.
24 * @param {Object} attrs Object liternal containing configuration parameters.
27 var Layout = function(el, config) {
28 if (Lang.isObject(el) && !el.tagName) {
32 if (Lang.isString(el)) {
43 attributes: config || {}
46 Layout.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
52 * @property _instances
53 * @description Internal hash table for all layout instances
56 Layout._instances = {};
59 * @method getLayoutById
60 * @description Get's a layout object by the HTML id of the element associated with the Layout object.
61 * @return {Object} The Layout Object
63 Layout.getLayoutById = function(id) {
64 if (Layout._instances[id]) {
65 return Layout._instances[id];
70 YAHOO.extend(Layout, YAHOO.util.Element, {
73 * @description A modified version of the YAHOO.env.ua object
78 b.standardsMode = false;
85 * @description An object literal that contains a list of units in the layout
92 * @description Set to true when the layout is rendered
99 * @description The zIndex to set all LayoutUnits to
106 * @description A collection of the current sizes of all usable LayoutUnits to be used for calculations
112 * @method _setBodySize
113 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
114 * @description Used to set the body size of the layout, sets the height and width of the parent container
116 _setBodySize: function(set) {
118 set = ((set === false) ? false : true);
121 h = Dom.getClientHeight();
122 w = Dom.getClientWidth();
124 h = parseInt(this.getStyle('height'), 10);
125 w = parseInt(this.getStyle('width'), 10);
127 w = this.get('element').clientWidth;
130 h = this.get('element').clientHeight;
133 if (this.get('minWidth')) {
134 if (w < this.get('minWidth')) {
135 w = this.get('minWidth');
138 if (this.get('minHeight')) {
139 if (h < this.get('minHeight')) {
140 h = this.get('minHeight');
150 Dom.setStyle(this._doc, 'height', h + 'px');
151 Dom.setStyle(this._doc, 'width', w + 'px');
153 this._sizes.doc = { h: h, w: w };
159 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
160 * @description Used to set the size and position of the left, right, top and bottom units
162 _setSides: function(set) {
163 var h1 = ((this._units.top) ? this._units.top.get('height') : 0),
164 h2 = ((this._units.bottom) ? this._units.bottom.get('height') : 0),
165 h = this._sizes.doc.h,
166 w = this._sizes.doc.w;
167 set = ((set === false) ? false : true);
170 h: h1, w: ((this._units.top) ? w : 0),
173 this._sizes.bottom = {
174 h: h2, w: ((this._units.bottom) ? w : 0)
177 var newH = (h - (h1 + h2));
180 h: newH, w: ((this._units.left) ? this._units.left.get('width') : 0)
182 this._sizes.right = {
183 h: newH, w: ((this._units.right) ? this._units.right.get('width') : 0),
184 l: ((this._units.right) ? (w - this._units.right.get('width')) : 0),
185 t: ((this._units.top) ? this._sizes.top.h : 0)
188 if (this._units.right && set) {
189 this._units.right.set('top', this._sizes.right.t);
190 if (!this._units.right._collapsing) {
191 this._units.right.set('left', this._sizes.right.l);
193 this._units.right.set('height', this._sizes.right.h, true);
195 if (this._units.left) {
196 this._sizes.left.l = 0;
197 if (this._units.top) {
198 this._sizes.left.t = this._sizes.top.h;
200 this._sizes.left.t = 0;
203 this._units.left.set('top', this._sizes.left.t);
204 this._units.left.set('height', this._sizes.left.h, true);
205 this._units.left.set('left', 0);
208 if (this._units.bottom) {
209 this._sizes.bottom.t = this._sizes.top.h + this._sizes.left.h;
211 this._units.bottom.set('top', this._sizes.bottom.t);
212 this._units.bottom.set('width', this._sizes.bottom.w, true);
215 if (this._units.top) {
217 this._units.top.set('width', this._sizes.top.w, true);
220 this._setCenter(set);
225 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
226 * @description Used to set the size and position of the center unit
228 _setCenter: function(set) {
229 set = ((set === false) ? false : true);
230 var h = this._sizes.left.h;
231 var w = (this._sizes.doc.w - (this._sizes.left.w + this._sizes.right.w));
233 this._units.center.set('height', h, true);
234 this._units.center.set('width', w, true);
235 this._units.center.set('top', this._sizes.top.h);
236 this._units.center.set('left', this._sizes.left.w);
238 this._sizes.center = { h: h, w: w, t: this._sizes.top.h, l: this._sizes.left.w };
242 * @description Get a reference to the internal Layout Unit sizes object used to build the layout wireframe
243 * @return {Object} An object of the layout unit sizes
245 getSizes: function() {
249 * @method getUnitById
250 * @param {String} id The HTML element id of the unit
251 * @description Get the LayoutUnit by it's HTML id
252 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
254 getUnitById: function(id) {
255 return YAHOO.widget.LayoutUnit.getLayoutUnitById(id);
258 * @method getUnitByPosition
259 * @param {String} pos The position of the unit in this layout
260 * @description Get the LayoutUnit by it's position in this layout
261 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
263 getUnitByPosition: function(pos) {
265 pos = pos.toLowerCase();
266 if (this._units[pos]) {
267 return this._units[pos];
275 * @param {Object} unit The LayoutUnit that you want to remove
276 * @description Remove the unit from this layout and resize the layout.
278 removeUnit: function(unit) {
279 delete this._units[unit.get('position')];
284 * @param {Object} cfg The config for the LayoutUnit that you want to add
285 * @description Add a unit to this layout and if the layout is rendered, resize the layout.
286 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
288 addUnit: function(cfg) {
292 if (this._units[cfg.position]) {
299 if (Dom.get(cfg.id)) {
300 element = Dom.get(cfg.id);
306 element = cfg.element;
310 el = document.createElement('div');
311 var id = Dom.generateId();
316 element = document.createElement('div');
318 Dom.addClass(element, 'yui-layout-wrap');
319 if (this.browser.ie && !this.browser.standardsMode) {
321 element.style.zoom = 1;
325 el.insertBefore(element, el.firstChild);
327 el.appendChild(element);
329 this._doc.appendChild(el);
331 var h = false, w = false;
334 h = parseInt(cfg.height, 10);
337 w = parseInt(cfg.width, 10);
340 YAHOO.lang.augmentObject(unitConfig, cfg); // break obj ref
342 unitConfig.parent = this;
343 unitConfig.wrap = element;
344 unitConfig.height = h;
345 unitConfig.width = w;
347 var unit = new YAHOO.widget.LayoutUnit(el, unitConfig);
349 unit.on('heightChange', this.resize, { unit: unit }, this);
350 unit.on('widthChange', this.resize, { unit: unit }, this);
351 unit.on('gutterChange', this.resize, { unit: unit }, this);
352 this._units[cfg.position] = unit;
354 if (this._rendered) {
362 * @method _createUnits
363 * @description Private method to create units from the config that was passed in.
365 _createUnits: function() {
366 var units = this.get('units');
367 for (var i in units) {
368 if (Lang.hasOwnProperty(units, i)) {
369 this.addUnit(units[i]);
375 * @param Boolean/Event set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units). This can also have an attribute event passed to it.
376 * @description Starts the chain of resize routines that will resize all the units.
377 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
379 resize: function(set, info) {
382 * If the event comes from an attribute and the value hasn't changed, don't process it.
385 if (ev && ev.prevValue && ev.newValue) {
386 if (ev.prevValue == ev.newValue) {
389 if (!info.unit.get('animate')) {
396 set = ((set === false) ? false : true);
398 var retVal = this.fireEvent('beforeResize');
399 if (retVal === false) {
402 if (this.browser.ie) {
404 Dom.removeClass(document.documentElement, 'yui-layout');
405 Dom.addClass(document.documentElement, 'yui-layout');
407 this.removeClass('yui-layout');
408 this.addClass('yui-layout');
412 this._setBodySize(set);
414 this.fireEvent('resize', { target: this, sizes: this._sizes, event: ev });
420 * @method _setupBodyElements
421 * @description Sets up the main doc element when using the body as the main element.
423 _setupBodyElements: function() {
424 this._doc = Dom.get('layout-doc');
426 this._doc = document.createElement('div');
427 this._doc.id = 'layout-doc';
428 if (document.body.firstChild) {
429 document.body.insertBefore(this._doc, document.body.firstChild);
431 document.body.appendChild(this._doc);
436 Event.on(window, 'resize', this.resize, this, true);
437 Dom.addClass(this._doc, 'yui-layout-doc');
441 * @method _setupElements
442 * @description Sets up the main doc element when not using the body as the main element.
444 _setupElements: function() {
445 this._doc = this.getElementsByClassName('yui-layout-doc')[0];
447 this._doc = document.createElement('div');
448 this.get('element').appendChild(this._doc);
452 Dom.addClass(this._doc, 'yui-layout-doc');
457 * @description Flag to determine if we are using the body as the root element.
464 * @description Reference to the root element
471 * @description The Layout class' initialization method
473 init: function(p_oElement, p_oAttributes) {
477 Layout.superclass.init.call(this, p_oElement, p_oAttributes);
479 if (this.get('parent')) {
480 this._zIndex = this.get('parent')._zIndex + 10;
487 if (!Lang.isString(id)) {
488 id = Dom.generateId(id);
490 Layout._instances[id] = this;
494 * @description This method starts the render process, applying classnames and creating elements
495 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
499 var el = this.get('element');
500 if (el && el.tagName && (el.tagName.toLowerCase() == 'body')) {
502 Dom.addClass(document.body, 'yui-layout');
503 if (Dom.hasClass(document.body, 'yui-skin-sam')) {
504 //Move the class up so we can have a css chain
505 Dom.addClass(document.documentElement, 'yui-skin-sam');
506 Dom.removeClass(document.body, 'yui-skin-sam');
508 this._setupBodyElements();
510 this._isBody = false;
511 this.addClass('yui-layout');
512 this._setupElements();
515 this._rendered = true;
516 this.fireEvent('render');
523 * @description Stamps the root node with a secure classname for ease of use. Also sets the this.browser.standardsMode variable.
526 if (document.compatMode == 'CSS1Compat') {
527 this.browser.standardsMode = true;
529 if (window.location.href.toLowerCase().indexOf("https") === 0) {
530 Dom.addClass(document.documentElement, 'secure');
531 this.browser.secure = true;
536 * @method initAttributes
537 * @description Processes the config
539 initAttributes: function(attr) {
540 Layout.superclass.initAttributes.call(this, attr);
543 * @description An array of config definitions for the LayoutUnits to add to this layout
546 this.setAttributeConfig('units', {
548 validator: YAHOO.lang.isArray,
549 value: attr.units || []
553 * @attribute minHeight
554 * @description The minimum height in pixels
557 this.setAttributeConfig('minHeight', {
558 value: attr.minHeight || false,
559 validator: YAHOO.lang.isNumber
563 * @attribute minWidth
564 * @description The minimum width in pixels
567 this.setAttributeConfig('minWidth', {
568 value: attr.minWidth || false,
569 validator: YAHOO.lang.isNumber
574 * @description The height in pixels
577 this.setAttributeConfig('height', {
578 value: attr.height || false,
579 validator: YAHOO.lang.isNumber,
580 method: function(h) {
584 this.setStyle('height', h + 'px');
590 * @description The width in pixels
593 this.setAttributeConfig('width', {
594 value: attr.width || false,
595 validator: YAHOO.lang.isNumber,
596 method: function(w) {
600 this.setStyle('width', w + 'px');
606 * @description If this layout is to be used as a child of another Layout instance, this config will bind the resize events together.
607 * @type Object YAHOO.widget.Layout
609 this.setAttributeConfig('parent', {
611 value: attr.parent || false,
612 method: function(p) {
614 p.on('resize', this.resize, this, true);
621 * @description Removes this layout from the page and destroys all units that it contains. This will destroy all data inside the layout and it's children.
623 destroy: function() {
624 var par = this.get('parent');
626 par.removeListener('resize', this.resize, this, true);
628 Event.removeListener(window, 'resize', this.resize, this, true);
630 this.unsubscribeAll();
631 for (var u in this._units) {
632 if (Lang.hasOwnProperty(this._units, u)) {
633 if (this._units[u]) {
634 this._units[u].destroy(true);
639 Event.purgeElement(this.get('element'), true);
640 this.get('parentNode').removeChild(this.get('element'));
642 delete YAHOO.widget.Layout._instances[this.get('id')];
643 //Brutal Object Destroy
644 for (var i in this) {
645 if (Lang.hasOwnProperty(this, i)) {
657 * @description Returns a string representing the Layout.
660 toString: function() {
662 return 'Layout #' + this.get('id');
669 * @description Fired when this.resize is called
670 * @type YAHOO.util.CustomEvent
674 * @description Fired when the Resize Utility for a Unit fires it's startResize Event.
675 * @type YAHOO.util.CustomEvent
678 * @event beforeResize
679 * @description Fires at the beginning of the resize method. If you return false, the resize is cancelled.
680 * @type YAHOO.util.CustomEvent
684 * @description Fired after the render method completes.
685 * @type YAHOO.util.CustomEvent
688 YAHOO.widget.Layout = Layout;
691 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
692 * @namespace YAHOO.widget
693 * @requires yahoo, dom, element, event, layout
694 * @optional animation, dragdrop, selector
697 var Dom = YAHOO.util.Dom,
698 Sel = YAHOO.util.Selector,
699 Event = YAHOO.util.Event,
705 * @extends YAHOO.util.Element
706 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
707 * @param {String/HTMLElement} el The element to make a unit.
708 * @param {Object} attrs Object liternal containing configuration parameters.
711 var LayoutUnit = function(el, config) {
715 attributes: config || {}
718 LayoutUnit.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
724 * @property _instances
725 * @description Internal hash table for all layout unit instances
728 LayoutUnit._instances = {};
731 * @method getLayoutUnitById
732 * @description Get's a layout unit object by the HTML id of the element associated with the Layout Unit object.
733 * @return {Object} The Layout Object
735 LayoutUnit.getLayoutUnitById = function(id) {
736 if (LayoutUnit._instances[id]) {
737 return LayoutUnit._instances[id];
742 YAHOO.extend(LayoutUnit, YAHOO.util.Element, {
744 * @property STR_CLOSE
745 * @description String used for close button title
748 STR_CLOSE: 'Click to close this pane.',
750 * @property STR_COLLAPSE
751 * @description String used for collapse button title
754 STR_COLLAPSE: 'Click to collapse this pane.',
756 * @property STR_EXPAND
757 * @description String used for expand button title
760 STR_EXPAND: 'Click to expand this pane.',
762 * The class name applied to dynamic tabs while loading.
763 * @property LOADING_CLASSNAME
765 * @default "disabled"
767 LOADING_CLASSNAME: 'loading',
770 * @description A modified version of the YAHOO.env.ua object
777 * @description A collection of the current sizes of the contents of this Layout Unit
784 * @description A reference to the Animation instance used by this LayouUnit
785 * @type YAHOO.util.Anim
791 * @description A reference to the Resize instance used by this LayoutUnit
792 * @type YAHOO.util.Resize
798 * @description A reference to the clip element used when collapsing the unit
805 * @description A simple hash table used to store the gutter to apply to the Unit
811 * @description A reference to the HTML element used for the Header
817 * @description A reference to the HTML element used for the body
823 * @description A reference to the HTML element used for the footer
829 * @property _collapsed
830 * @description Flag to determine if the unit is collapsed or not.
836 * @property _collapsing
837 * @description A flag set while the unit is being collapsed, used so we don't fire events while animating the size
843 * @property _lastWidth
844 * @description A holder for the last known width of the unit
850 * @property _lastHeight
851 * @description A holder for the last known height of the unit
858 * @description A holder for the last known top of the unit
864 * @property _lastLeft
865 * @description A holder for the last known left of the unit
871 * @property _lastScroll
872 * @description A holder for the last known scroll state of the unit
878 * @property _lastCenetrScroll
879 * @description A holder for the last known scroll state of the center unit
882 _lastCenterScroll: null,
885 * @property _lastScrollTop
886 * @description A holder for the last known scrollTop state of the unit
889 _lastScrollTop: null,
892 * @description Resize either the unit or it's clipped state, also updating the box inside
893 * @param {Boolean} force This will force full calculations even when the unit is collapsed
894 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
896 resize: function(force) {
897 var retVal = this.fireEvent('beforeResize');
898 if (retVal === false) {
901 if (!this._collapsing || (force === true)) {
902 var scroll = this.get('scroll');
903 this.set('scroll', false);
906 var hd = this._getBoxSize(this.header),
907 ft = this._getBoxSize(this.footer),
908 box = [this.get('height'), this.get('width')];
910 var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
911 nw = box[1] - (this._gutter.left + this._gutter.right);
913 var wrapH = (nh + (hd[0] + ft[0])),
916 if (this._collapsed && !this._collapsing) {
917 this._setHeight(this._clip, wrapH);
918 this._setWidth(this._clip, wrapW);
919 Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
920 Dom.setStyle(this._clip, 'left', this.get('left') + this._gutter.left + 'px');
921 } else if (!this._collapsed || (this._collapsed && this._collapsing)) {
922 wrapH = this._setHeight(this.get('wrap'), wrapH);
923 wrapW = this._setWidth(this.get('wrap'), wrapW);
924 this._sizes.wrap.h = wrapH;
925 this._sizes.wrap.w = wrapW;
927 Dom.setStyle(this.get('wrap'), 'top', this._gutter.top + 'px');
928 Dom.setStyle(this.get('wrap'), 'left', this._gutter.left + 'px');
930 this._sizes.header.w = this._setWidth(this.header, wrapW);
931 this._sizes.header.h = hd[0];
933 this._sizes.footer.w = this._setWidth(this.footer, wrapW);
934 this._sizes.footer.h = ft[0];
936 Dom.setStyle(this.footer, 'bottom', '0px');
938 this._sizes.body.h = this._setHeight(this.body, (wrapH - (hd[0] + ft[0])));
939 this._sizes.body.w =this._setWidth(this.body, wrapW);
940 Dom.setStyle(this.body, 'top', hd[0] + 'px');
942 this.set('scroll', scroll);
943 this.fireEvent('resize');
951 * @description Sets the width of the element based on the border size of the element.
952 * @param {HTMLElement} el The HTMLElement to have it's width set
953 * @param {Number} w The width that you want it the element set to
954 * @return {Number} The new width, fixed for borders and IE QuirksMode
956 _setWidth: function(el, w) {
958 var b = this._getBorderSizes(el);
959 w = (w - (b[1] + b[3]));
960 w = this._fixQuirks(el, w, 'w');
964 Dom.setStyle(el, 'width', w + 'px');
971 * @description Sets the height of the element based on the border size of the element.
972 * @param {HTMLElement} el The HTMLElement to have it's height set
973 * @param {Number} h The height that you want it the element set to
974 * @return {Number} The new height, fixed for borders and IE QuirksMode
976 _setHeight: function(el, h) {
978 var b = this._getBorderSizes(el);
979 h = (h - (b[0] + b[2]));
980 h = this._fixQuirks(el, h, 'h');
984 Dom.setStyle(el, 'height', h + 'px');
991 * @description Fixes the box calculations for IE in QuirksMode
992 * @param {HTMLElement} el The HTMLElement to set the dimension on
993 * @param {Number} dim The number of the dimension to fix
994 * @param {String} side The dimension (h or w) to fix. Defaults to h
995 * @return {Number} The fixed dimension
997 _fixQuirks: function(el, dim, side) {
1003 if ((this.browser.ie < 8) && !this.browser.standardsMode) {
1004 //Internet Explorer - Quirks Mode
1005 var b = this._getBorderSizes(el),
1006 bp = this._getBorderSizes(el.parentNode);
1007 if ((b[i1] === 0) && (b[i2] === 0)) { //No Borders, check parent
1008 if ((bp[i1] !== 0) && (bp[i2] !== 0)) { //Parent has Borders
1009 dim = (dim - (bp[i1] + bp[i2]));
1012 if ((bp[i1] === 0) && (bp[i2] === 0)) {
1013 dim = (dim + (b[i1] + b[i2]));
1021 * @method _getBoxSize
1022 * @description Get's the elements clientHeight and clientWidth plus the size of the borders
1023 * @param {HTMLElement} el The HTMLElement to get the size of
1024 * @return {Array} An array of height and width
1026 _getBoxSize: function(el) {
1029 if (this.browser.ie && !this.browser.standardsMode) {
1032 var b = this._getBorderSizes(el);
1033 size[0] = el.clientHeight + (b[0] + b[2]);
1034 size[1] = el.clientWidth + (b[1] + b[3]);
1040 * @method _getBorderSizes
1041 * @description Get the CSS border size of the element passed.
1042 * @param {HTMLElement} el The element to get the border size of
1043 * @return {Array} An array of the top, right, bottom, left borders.
1045 _getBorderSizes: function(el) {
1047 el = el || this.get('element');
1048 if (this.browser.ie && !this.browser.standardsMode) {
1051 s[0] = parseInt(Dom.getStyle(el, 'borderTopWidth'), 10);
1052 s[1] = parseInt(Dom.getStyle(el, 'borderRightWidth'), 10);
1053 s[2] = parseInt(Dom.getStyle(el, 'borderBottomWidth'), 10);
1054 s[3] = parseInt(Dom.getStyle(el, 'borderLeftWidth'), 10);
1056 //IE will return NaN on these if they are set to auto, we'll set them to 0
1057 for (var i = 0; i < s.length; i++) {
1066 * @method _createClip
1067 * @description Create the clip element used when the Unit is collapsed
1069 _createClip: function() {
1071 this._clip = document.createElement('div');
1072 this._clip.className = 'yui-layout-clip yui-layout-clip-' + this.get('position');
1073 this._clip.innerHTML = '<div class="collapse"></div>';
1074 var c = this._clip.firstChild;
1075 c.title = this.STR_EXPAND;
1076 Event.on(c, 'click', this.expand, this, true);
1077 this.get('element').parentNode.appendChild(this._clip);
1082 * @method _toggleClip
1083 * @description Toggle th current state of the Clip element and set it's height, width and position
1085 _toggleClip: function() {
1086 if (!this._collapsed) {
1088 var hd = this._getBoxSize(this.header),
1089 ft = this._getBoxSize(this.footer),
1090 box = [this.get('height'), this.get('width')];
1093 var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
1094 nw = box[1] - (this._gutter.left + this._gutter.right),
1095 wrapH = (nh + (hd[0] + ft[0]));
1097 switch (this.get('position')) {
1100 this._setWidth(this._clip, nw);
1101 this._setHeight(this._clip, this.get('collapseSize'));
1102 Dom.setStyle(this._clip, 'left', (this._lastLeft + this._gutter.left) + 'px');
1103 if (this.get('position') == 'bottom') {
1104 Dom.setStyle(this._clip, 'top', ((this._lastTop + this._lastHeight) - (this.get('collapseSize') - this._gutter.top)) + 'px');
1106 Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
1111 this._setWidth(this._clip, this.get('collapseSize'));
1112 this._setHeight(this._clip, wrapH);
1113 Dom.setStyle(this._clip, 'top', (this.get('top') + this._gutter.top) + 'px');
1114 if (this.get('position') == 'right') {
1115 Dom.setStyle(this._clip, 'left', (((this._lastLeft + this._lastWidth) - this.get('collapseSize')) - this._gutter.left) + 'px');
1117 Dom.setStyle(this._clip, 'left', (this.get('left') + this._gutter.left) + 'px');
1122 Dom.setStyle(this._clip, 'display', 'block');
1123 this.setStyle('display', 'none');
1126 Dom.setStyle(this._clip, 'display', 'none');
1131 * @description Get a reference to the internal sizes object for this unit
1132 * @return {Object} An object of the sizes used for calculations
1134 getSizes: function() {
1139 * @description Toggles the Unit, replacing it with a clipped version.
1140 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1142 toggle: function() {
1143 if (this._collapsed) {
1152 * @description Expand the Unit if it is collapsed.
1153 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1155 expand: function() {
1156 if (!this._collapsed) {
1159 var retVal = this.fireEvent('beforeExpand');
1160 if (retVal === false) {
1164 this._collapsing = true;
1165 this.setStyle('zIndex', this._zIndex);
1168 this.setStyle('display', 'none');
1171 switch (this.get('position')) {
1174 this.set('width', this._lastWidth, true);
1175 this.setStyle('width', this._lastWidth + 'px');
1176 this.get('parent').resize(false);
1177 s = this.get('parent').getSizes()[this.get('position')];
1178 this.set('height', s.h, true);
1185 if (this.get('position') == 'left') {
1186 attr.left.from = (left - s.w);
1187 this.setStyle('left', (left - s.w) + 'px');
1192 this.set('height', this._lastHeight, true);
1193 this.setStyle('height', this._lastHeight + 'px');
1194 this.get('parent').resize(false);
1195 s = this.get('parent').getSizes()[this.get('position')];
1196 this.set('width', s.w, true);
1203 if (this.get('position') == 'top') {
1204 this.setStyle('top', (top - s.h) + 'px');
1205 attr.top.from = (top - s.h);
1210 this._anim.attributes = attr;
1211 var exStart = function() {
1212 this.setStyle('display', 'block');
1214 this._anim.onStart.unsubscribe(exStart, this, true);
1216 var expand = function() {
1217 this._collapsing = false;
1218 this.setStyle('zIndex', this._zIndex);
1219 this.set('width', this._lastWidth);
1220 this.set('height', this._lastHeight);
1221 this._collapsed = false;
1223 this.set('scroll', this._lastScroll);
1224 if (this._lastScrollTop > 0) {
1225 this.body.scrollTop = this._lastScrollTop;
1227 this._anim.onComplete.unsubscribe(expand, this, true);
1228 this.fireEvent('expand');
1230 this._anim.onStart.subscribe(exStart, this, true);
1231 this._anim.onComplete.subscribe(expand, this, true);
1232 this._anim.animate();
1235 this._collapsing = false;
1237 this._collapsed = false;
1238 this._zIndex = this.getStyle('zIndex');
1239 this.setStyle('zIndex', this.get('parent')._zIndex);
1240 this.setStyle('display', 'block');
1241 this.set('width', this._lastWidth);
1242 this.set('height', this._lastHeight);
1244 this.set('scroll', this._lastScroll);
1245 if (this._lastScrollTop > 0) {
1246 this.body.scrollTop = this._lastScrollTop;
1248 this.fireEvent('expand');
1254 * @description Collapse the Unit if it is not collapsed.
1255 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1257 collapse: function() {
1258 if (this._collapsed) {
1261 var retValue = this.fireEvent('beforeCollapse');
1262 if (retValue === false) {
1268 this._collapsing = true;
1269 var w = this.get('width'),
1270 h = this.get('height'),
1272 this._lastWidth = w;
1273 this._lastHeight = h;
1274 this._lastScroll = this.get('scroll');
1275 this._lastScrollTop = this.body.scrollTop;
1276 this.set('scroll', false, true);
1277 this._lastLeft = parseInt(this.get('element').style.left, 10);
1278 this._lastTop = parseInt(this.get('element').style.top, 10);
1279 if (isNaN(this._lastTop)) {
1283 if (isNaN(this._lastLeft)) {
1285 this.set('left', 0);
1287 this._zIndex = this.getStyle('zIndex');
1288 this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1289 var pos = this.get('position');
1294 this.set('height', (this.get('collapseSize') + (this._gutter.top + this._gutter.bottom)));
1297 to: (this.get('top') - h)
1300 if (pos == 'bottom') {
1301 attr.top.to = (this.get('top') + h);
1306 this.set('width', (this.get('collapseSize') + (this._gutter.left + this._gutter.right)));
1309 to: -(this._lastWidth)
1312 if (pos == 'right') {
1314 to: (this.get('left') + w)
1320 this._anim.attributes = attr;
1321 var collapse = function() {
1322 this._collapsing = false;
1324 this.setStyle('zIndex', this.get('parent')._zIndex);
1325 this._collapsed = true;
1326 this.get('parent').resize();
1327 this._anim.onComplete.unsubscribe(collapse, this, true);
1328 this.fireEvent('collapse');
1330 this._anim.onComplete.subscribe(collapse, this, true);
1331 this._anim.animate();
1333 this._collapsing = false;
1334 this.setStyle('display', 'none');
1336 this.setStyle('zIndex', this.get('parent')._zIndex);
1337 this.get('parent').resize();
1338 this._collapsed = true;
1339 this.fireEvent('collapse');
1345 * @description Close the unit, removing it from the parent Layout.
1346 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
1349 this.setStyle('display', 'none');
1350 this.get('parent').removeUnit(this);
1351 this.fireEvent('close');
1353 this._clip.parentNode.removeChild(this._clip);
1356 return this.get('parent');
1359 * @property loadHandler
1360 * @description Callback method for the YUI Connection Manager used for load the body using AJAX. NOTE: e.responseText is loaded via innerHTML.
1364 success: function(o) {
1365 this.body.innerHTML = o.responseText;
1368 failure: function(o) {
1372 * @property dataConnection
1373 * @description YUI Connection Manager handler
1376 dataConnection: null,
1379 * @property _loading
1380 * @description During the loading process this variable will be true
1385 * @method loadContent
1386 * @description Loading the content of the unit using the connection manager
1387 * @return {object} YUI Connection Manager handler
1389 loadContent: function() {
1390 // load dynamic content unless already loading or loaded and caching
1391 if (YAHOO.util.Connect && this.get('dataSrc') && !this._loading && !this.get('dataLoaded')) {
1392 this._loading = true;
1393 Dom.addClass(this.body, this.LOADING_CLASSNAME);
1394 this.dataConnection = YAHOO.util.Connect.asyncRequest(
1395 this.get('loadMethod'),
1396 this.get('dataSrc'),
1398 success: function(o) {
1399 this.loadHandler.success.call(this, o);
1400 this.set('dataLoaded', true);
1401 this.dataConnection = null;
1402 Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1403 this._loading = false;
1404 this.fireEvent('load');
1406 failure: function(o) {
1407 this.loadHandler.failure.call(this, o);
1408 this.dataConnection = null;
1409 Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1410 this._loading = false;
1411 this.fireEvent('loadError', { error: o });
1414 timeout: this.get('dataTimeout')
1417 return this.dataConnection;
1424 * @description The initalization method inherited from Element.
1426 init: function(p_oElement, p_oAttributes) {
1452 LayoutUnit.superclass.init.call(this, p_oElement, p_oAttributes);
1454 this.browser = this.get('parent').browser;
1456 var id = p_oElement;
1457 if (!Lang.isString(id)) {
1458 id = Dom.generateId(id);
1460 LayoutUnit._instances[id] = this;
1462 this.setStyle('position', 'absolute');
1464 this.addClass('yui-layout-unit');
1465 this.addClass('yui-layout-unit-' + this.get('position'));
1468 var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1470 this.header = header;
1472 var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1476 var footer = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1478 this.footer = footer;
1481 this.on('contentChange', this.resize, this, true);
1482 this._lastScrollTop = 0;
1484 this.set('animate', this.get('animate'));
1488 * @method initAttributes
1489 * @description Processes the config
1491 initAttributes: function(attr) {
1492 LayoutUnit.superclass.initAttributes.call(this, attr);
1497 * @description A reference to the wrap element
1500 this.setAttributeConfig('wrap', {
1501 value: attr.wrap || null,
1502 method: function(w) {
1504 var id = Dom.generateId(w);
1505 LayoutUnit._instances[id] = this;
1511 * @description Set this option to true if you want the LayoutUnit to fix the first layer of YUI CSS Grids (margins)
1514 this.setAttributeConfig('grids', {
1515 value: attr.grids || false
1520 * @description The current top positioning of the Unit
1523 this.setAttributeConfig('top', {
1524 value: attr.top || 0,
1525 validator: Lang.isNumber,
1526 method: function(t) {
1527 if (!this._collapsing) {
1528 this.setStyle('top', t + 'px');
1535 * @description The current left position of the Unit
1538 this.setAttributeConfig('left', {
1539 value: attr.left || 0,
1540 validator: Lang.isNumber,
1541 method: function(l) {
1542 if (!this._collapsing) {
1543 this.setStyle('left', l + 'px');
1549 * @attribute minWidth
1550 * @description The minWidth parameter passed to the Resize Utility
1553 this.setAttributeConfig('minWidth', {
1554 value: attr.minWidth || false,
1555 method: function(v) {
1557 this._resize.set('minWidth', v);
1560 validator: YAHOO.lang.isNumber
1564 * @attribute maxWidth
1565 * @description The maxWidth parameter passed to the Resize Utility
1568 this.setAttributeConfig('maxWidth', {
1569 value: attr.maxWidth || false,
1570 method: function(v) {
1572 this._resize.set('maxWidth', v);
1575 validator: YAHOO.lang.isNumber
1579 * @attribute minHeight
1580 * @description The minHeight parameter passed to the Resize Utility
1583 this.setAttributeConfig('minHeight', {
1584 value: attr.minHeight || false,
1585 method: function(v) {
1587 this._resize.set('minHeight', v);
1590 validator: YAHOO.lang.isNumber
1594 * @attribute maxHeight
1595 * @description The maxHeight parameter passed to the Resize Utility
1598 this.setAttributeConfig('maxHeight', {
1599 value: attr.maxHeight || false,
1600 method: function(v) {
1602 this._resize.set('maxHeight', v);
1605 validator: YAHOO.lang.isNumber
1610 * @description The height of the Unit
1613 this.setAttributeConfig('height', {
1615 validator: Lang.isNumber,
1616 method: function(h) {
1617 if (!this._collapsing) {
1621 this.setStyle('height', h + 'px');
1628 * @description The width of the Unit
1631 this.setAttributeConfig('width', {
1633 validator: Lang.isNumber,
1634 method: function(w) {
1635 if (!this._collapsing) {
1639 this.setStyle('width', w + 'px');
1645 * @description The CSS zIndex to give to the unit, so you can have overlapping elements such as menus in a unit.
1648 this.setAttributeConfig('zIndex', {
1649 value: attr.zIndex || false,
1650 method: function(z) {
1651 this.setStyle('zIndex', z);
1655 * @attribute position
1656 * @description The position (top, right, bottom, left or center) of the Unit in the Layout
1659 this.setAttributeConfig('position', {
1660 value: attr.position
1664 * @description The gutter that we should apply to the parent Layout around this Unit. Supports standard CSS markup: (2 4 0 5) or (2) or (2 5)
1667 this.setAttributeConfig('gutter', {
1668 value: attr.gutter || 0,
1669 validator: YAHOO.lang.isString,
1670 method: function(gutter) {
1671 var p = gutter.split(' ');
1673 this._gutter.top = parseInt(p[0], 10);
1675 this._gutter.right = parseInt(p[1], 10);
1677 this._gutter.right = this._gutter.top;
1680 this._gutter.bottom = parseInt(p[2], 10);
1682 this._gutter.bottom = this._gutter.top;
1685 this._gutter.left = parseInt(p[3], 10);
1687 this._gutter.left = this._gutter.right;
1689 this._gutter.left = this._gutter.top;
1696 * @description The parent Layout that we are assigned to
1697 * @type {Object} YAHOO.widget.Layout
1699 this.setAttributeConfig('parent', {
1701 value: attr.parent || false,
1702 method: function(p) {
1704 p.on('resize', this.resize, this, true);
1710 * @attribute collapseSize
1711 * @description The pixel size of the Clip that we will collapse to
1714 this.setAttributeConfig('collapseSize', {
1715 value: attr.collapseSize || 25,
1716 validator: YAHOO.lang.isNumber
1719 * @attribute duration
1720 * @description The duration to give the Animation Utility when animating the opening and closing of Units
1722 this.setAttributeConfig('duration', {
1723 value: attr.duration || 0.5
1727 * @description The Animation Easing to apply to the Animation instance for this unit.
1729 this.setAttributeConfig('easing', {
1730 value: attr.easing || ((YAHOO.util && YAHOO.util.Easing) ? YAHOO.util.Easing.BounceIn : 'false')
1733 * @attribute animate
1734 * @description Use animation to collapse/expand the unit
1737 this.setAttributeConfig('animate', {
1738 value: ((attr.animate === false) ? false : true),
1739 validator: function() {
1741 if (YAHOO.util.Anim) {
1746 method: function(anim) {
1748 this._anim = new YAHOO.util.Anim(this.get('element'), {}, this.get('duration'), this.get('easing'));
1756 * @description The html to use as the Header of the Unit (sets via innerHTML)
1759 this.setAttributeConfig('header', {
1760 value: attr.header || false,
1761 method: function(txt) {
1762 if (txt === false) {
1765 Dom.addClass(this.body, 'yui-layout-bd-nohd');
1766 this.header.parentNode.removeChild(this.header);
1771 var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1773 header = this._createHeader();
1775 this.header = header;
1777 var h = this.header.getElementsByTagName('h2')[0];
1779 h = document.createElement('h2');
1780 this.header.appendChild(h);
1784 Dom.removeClass(this.body, 'yui-layout-bd-nohd');
1787 this.fireEvent('contentChange', { target: 'header' });
1792 * @description Use the proxy config setting for the Resize Utility
1795 this.setAttributeConfig('proxy', {
1797 value: ((attr.proxy === false) ? false : true)
1801 * @description The content for the body. If we find an element in the page with an id that matches the passed option we will move that element into the body of this unit. (sets via innerHTML)
1804 this.setAttributeConfig('body', {
1805 value: attr.body || false,
1806 method: function(content) {
1808 var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1812 body = document.createElement('div');
1813 body.className = 'yui-layout-bd';
1815 this.get('wrap').appendChild(body);
1819 Dom.addClass(this.body, 'yui-layout-bd-nohd');
1821 Dom.addClass(this.body, 'yui-layout-bd-noft');
1825 if (Lang.isString(content)) {
1826 el = Dom.get(content);
1827 } else if (content && content.tagName) {
1831 var id = Dom.generateId(el);
1832 LayoutUnit._instances[id] = this;
1833 this.body.appendChild(el);
1835 this.body.innerHTML = content;
1840 this.fireEvent('contentChange', { target: 'body' });
1846 * @description The content for the footer. If we find an element in the page with an id that matches the passed option we will move that element into the footer of this unit. (sets via innerHTML)
1849 this.setAttributeConfig('footer', {
1850 value: attr.footer || false,
1851 method: function(content) {
1852 if (content === false) {
1855 Dom.addClass(this.body, 'yui-layout-bd-noft');
1856 this.footer.parentNode.removeChild(this.footer);
1861 var ft = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1863 ft = document.createElement('div');
1864 ft.className = 'yui-layout-ft';
1866 this.get('wrap').appendChild(ft);
1872 if (Lang.isString(content)) {
1873 el = Dom.get(content);
1874 } else if (content && content.tagName) {
1878 this.footer.appendChild(el);
1880 this.footer.innerHTML = content;
1882 Dom.removeClass(this.body, 'yui-layout-bd-noft');
1884 this.fireEvent('contentChange', { target: 'footer' });
1889 * @description Adds a close icon to the unit
1891 this.setAttributeConfig('close', {
1892 value: attr.close || false,
1893 method: function(close) {
1894 //Position Center doesn't get this
1895 if (this.get('position') == 'center') {
1898 if (!this.header && close) {
1899 this._createHeader();
1904 var c = this.header ? Dom.getElementsByClassName('close', 'div', this.header)[0] : null;
1907 //Force some header text if there isn't any
1908 if (!this.get('header')) {
1909 this.set('header', ' ');
1912 c = document.createElement('div');
1913 c.className = 'close';
1914 this.header.appendChild(c);
1915 Event.on(c, 'click', this.close, this, true);
1917 c.title = this.STR_CLOSE;
1918 } else if (c && c.parentNode) {
1919 Event.purgeElement(c);
1920 c.parentNode.removeChild(c);
1922 this._configs.close.value = close;
1923 this.set('collapse', this.get('collapse')); //Reset so we get the right classnames
1928 * @attribute collapse
1929 * @description Adds a collapse icon to the unit
1931 this.setAttributeConfig('collapse', {
1932 value: attr.collapse || false,
1933 method: function(collapse) {
1934 //Position Center doesn't get this
1935 if (this.get('position') == 'center') {
1938 if (!this.header && collapse) {
1939 this._createHeader();
1944 var c = this.header ? Dom.getElementsByClassName('collapse', 'div', this.header)[0] : null;
1947 //Force some header text if there isn't any
1948 if (!this.get('header')) {
1949 this.set('header', ' ');
1952 c = document.createElement('div');
1953 this.header.appendChild(c);
1954 Event.on(c, 'click', this.collapse, this, true);
1956 c.title = this.STR_COLLAPSE;
1957 c.className = 'collapse' + ((this.get('close')) ? ' collapse-close' : '');
1958 } else if (c && c.parentNode) {
1959 Event.purgeElement(c);
1960 c.parentNode.removeChild(c);
1966 * @description Adds a class to the unit to allow for overflow: auto (yui-layout-scroll), default is overflow: hidden (yui-layout-noscroll). If true scroll bars will be placed on the element when the content exceeds the given area, false will put overflow hidden to hide the content. Passing null will render the content as usual overflow.
1967 * @type Boolean/Null
1970 this.setAttributeConfig('scroll', {
1971 value: (((attr.scroll === true) || (attr.scroll === false) || (attr.scroll === null)) ? attr.scroll : false),
1972 method: function(scroll) {
1973 if ((scroll === false) && !this._collapsed) { //Removing scroll bar
1975 if (this.body.scrollTop > 0) {
1976 this._lastScrollTop = this.body.scrollTop;
1981 if (scroll === true) {
1982 this.addClass('yui-layout-scroll');
1983 this.removeClass('yui-layout-noscroll');
1984 if (this._lastScrollTop > 0) {
1986 this.body.scrollTop = this._lastScrollTop;
1989 } else if (scroll === false) {
1990 this.removeClass('yui-layout-scroll');
1991 this.addClass('yui-layout-noscroll');
1992 } else if (scroll === null) {
1993 this.removeClass('yui-layout-scroll');
1994 this.removeClass('yui-layout-noscroll');
2000 * @description Config option to pass to the Resize Utility
2002 this.setAttributeConfig('hover', {
2004 value: attr.hover || false,
2005 validator: YAHOO.lang.isBoolean
2008 * @attribute useShim
2009 * @description Config option to pass to the Resize Utility
2011 this.setAttributeConfig('useShim', {
2012 value: attr.useShim || false,
2013 validator: YAHOO.lang.isBoolean,
2014 method: function(u) {
2016 this._resize.set('useShim', u);
2022 * @description Should a Resize instance be added to this unit
2025 this.setAttributeConfig('resize', {
2026 value: attr.resize || false,
2027 validator: function(r) {
2028 if (YAHOO.util && YAHOO.util.Resize) {
2033 method: function(resize) {
2034 if (resize && !this._resize) {
2035 //Position Center doesn't get this
2036 if (this.get('position') == 'center') {
2039 var handle = false; //To catch center
2040 switch (this.get('position')) {
2055 this.setStyle('position', 'absolute'); //Make sure Resize get's a position
2058 this._resize = new YAHOO.util.Resize(this.get('element'), {
2059 proxy: this.get('proxy'),
2060 hover: this.get('hover'),
2064 minWidth: this.get('minWidth'),
2065 maxWidth: this.get('maxWidth'),
2066 minHeight: this.get('minHeight'),
2067 maxHeight: this.get('maxHeight'),
2068 height: this.get('height'),
2069 width: this.get('width'),
2071 useShim: this.get('useShim'),
2075 this._resize._handles[handle].innerHTML = '<div class="yui-layout-resize-knob"></div>';
2077 if (this.get('proxy')) {
2078 var proxy = this._resize.getProxyEl();
2079 proxy.innerHTML = '<div class="yui-layout-handle-' + handle + '"></div>';
2081 this._resize.on('startResize', function(ev) {
2082 this._lastScroll = this.get('scroll');
2083 this.set('scroll', false);
2084 if (this.get('parent')) {
2085 this.get('parent').fireEvent('startResize');
2086 var c = this.get('parent').getUnitByPosition('center');
2087 this._lastCenterScroll = c.get('scroll');
2088 c.addClass(this._resize.CSS_RESIZING);
2089 c.set('scroll', false);
2091 this.fireEvent('startResize');
2093 this._resize.on('resize', function(ev) {
2094 this.set('height', ev.height);
2095 this.set('width', ev.width);
2097 this._resize.on('endResize', function(ev) {
2098 this.set('scroll', this._lastScroll);
2099 if (this.get('parent')) {
2100 var c = this.get('parent').getUnitByPosition('center');
2101 c.set('scroll', this._lastCenterScroll);
2102 c.removeClass(this._resize.CSS_RESIZING);
2105 this.fireEvent('endResize');
2110 this._resize.destroy();
2116 * The unit data source, used for loading content dynamically.
2117 * @attribute dataSrc
2120 this.setAttributeConfig('dataSrc', {
2124 * The method to use for the data request.
2125 * @attribute loadMethod
2129 this.setAttributeConfig('loadMethod', {
2130 value: attr.loadMethod || 'GET',
2131 validator: YAHOO.lang.isString
2134 * Whether or not any data has been loaded from the server.
2135 * @attribute dataLoaded
2138 this.setAttributeConfig('dataLoaded', {
2140 validator: YAHOO.lang.isBoolean,
2144 * Number if milliseconds before aborting and calling failure handler.
2145 * @attribute dataTimeout
2149 this.setAttributeConfig('dataTimeout', {
2150 value: attr.dataTimeout || null,
2151 validator: YAHOO.lang.isNumber
2156 * @method _cleanGrids
2157 * @description This method attempts to clean up the first level of the YUI CSS Grids, YAHOO.util.Selector is required for this operation.
2159 _cleanGrids: function() {
2160 if (this.get('grids')) {
2161 var b = Sel.query('div.yui-b', this.body, true);
2163 Dom.removeClass(b, 'yui-b');
2165 Event.onAvailable('yui-main', function() {
2166 Dom.setStyle(Sel.query('#yui-main'), 'margin-left', '0');
2167 Dom.setStyle(Sel.query('#yui-main'), 'margin-right', '0');
2173 * @method _createHeader
2174 * @description Creates the HTMLElement for the header
2175 * @return {HTMLElement} The new HTMLElement
2177 _createHeader: function() {
2178 var header = document.createElement('div');
2179 header.className = 'yui-layout-hd';
2180 if (this.get('firstChild')) {
2181 this.get('wrap').insertBefore(header, this.get('wrap').firstChild);
2183 this.get('wrap').appendChild(header);
2185 this.header = header;
2190 * @param {Boolean} force Don't report to the parent, because we are being called from the parent.
2191 * @description Removes this unit from the parent and cleans up after itself.
2192 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
2194 destroy: function(force) {
2196 this._resize.destroy();
2198 var par = this.get('parent');
2200 this.setStyle('display', 'none');
2202 this._clip.parentNode.removeChild(this._clip);
2207 par.removeUnit(this);
2211 par.removeListener('resize', this.resize, this, true);
2213 this.unsubscribeAll();
2214 Event.purgeElement(this.get('element'), true);
2215 this.get('parentNode').removeChild(this.get('element'));
2217 delete YAHOO.widget.LayoutUnit._instances[this.get('id')];
2218 //Brutal Object Destroy
2219 for (var i in this) {
2220 if (Lang.hasOwnProperty(this, i)) {
2230 * @description Returns a string representing the LayoutUnit.
2233 toString: function() {
2235 return 'LayoutUnit #' + this.get('id') + ' (' + this.get('position') + ')';
2237 return 'LayoutUnit';
2241 * @description Fired when this.resize is called
2242 * @type YAHOO.util.CustomEvent
2245 * @event startResize
2246 * @description Fired when the Resize Utility fires it's startResize Event.
2247 * @type YAHOO.util.CustomEvent
2251 * @description Fired when the Resize Utility fires it's endResize Event.
2252 * @type YAHOO.util.CustomEvent
2255 * @event beforeResize
2256 * @description Fired at the beginning of the resize method. If you return false, the resize is cancelled.
2257 * @type YAHOO.util.CustomEvent
2260 * @event contentChange
2261 * @description Fired when the content in the header, body or footer is changed via the API
2262 * @type YAHOO.util.CustomEvent
2266 * @description Fired when the unit is closed
2267 * @type YAHOO.util.CustomEvent
2270 * @event beforeCollapse
2271 * @description Fired before the unit is collapsed. If you return false, the collapse is cancelled.
2272 * @type YAHOO.util.CustomEvent
2276 * @description Fired when the unit is collapsed
2277 * @type YAHOO.util.CustomEvent
2281 * @description Fired when the unit is exanded
2282 * @type YAHOO.util.CustomEvent
2285 * @event beforeExpand
2286 * @description Fired before the unit is exanded. If you return false, the collapse is cancelled.
2287 * @type YAHOO.util.CustomEvent
2291 * @description Fired when data is loaded via the dataSrc config.
2292 * @type YAHOO.util.CustomEvent
2296 * @description Fired when an error occurs loading data via the dataSrc config. Error message is passed as argument to this event.
2297 * @type YAHOO.util.CustomEvent
2301 YAHOO.widget.LayoutUnit = LayoutUnit;
2303 YAHOO.register("layout", YAHOO.widget.Layout, {version: "2.9.0", build: "2800"});