2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
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 YAHOO.log('Creating the Layout Object', 'info', 'Layout');
29 if (Lang.isObject(el) && !el.tagName) {
33 if (Lang.isString(el)) {
44 attributes: config || {}
47 Layout.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
53 * @property _instances
54 * @description Internal hash table for all layout instances
57 Layout._instances = {};
60 * @method getLayoutById
61 * @description Get's a layout object by the HTML id of the element associated with the Layout object.
62 * @return {Object} The Layout Object
64 Layout.getLayoutById = function(id) {
65 if (Layout._instances[id]) {
66 return Layout._instances[id];
71 YAHOO.extend(Layout, YAHOO.util.Element, {
74 * @description A modified version of the YAHOO.env.ua object
79 b.standardsMode = false;
86 * @description An object literal that contains a list of units in the layout
93 * @description Set to true when the layout is rendered
100 * @description The zIndex to set all LayoutUnits to
107 * @description A collection of the current sizes of all usable LayoutUnits to be used for calculations
113 * @method _setBodySize
114 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
115 * @description Used to set the body size of the layout, sets the height and width of the parent container
117 _setBodySize: function(set) {
119 set = ((set === false) ? false : true);
122 h = Dom.getClientHeight();
123 w = Dom.getClientWidth();
125 h = parseInt(this.getStyle('height'), 10);
126 w = parseInt(this.getStyle('width'), 10);
128 w = this.get('element').clientWidth;
131 h = this.get('element').clientHeight;
134 if (this.get('minWidth')) {
135 if (w < this.get('minWidth')) {
136 w = this.get('minWidth');
139 if (this.get('minHeight')) {
140 if (h < this.get('minHeight')) {
141 h = this.get('minHeight');
151 Dom.setStyle(this._doc, 'height', h + 'px');
152 Dom.setStyle(this._doc, 'width', w + 'px');
154 this._sizes.doc = { h: h, w: w };
155 YAHOO.log('Setting Body height and width: (' + h + ',' + w + ')', 'info', 'Layout');
161 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
162 * @description Used to set the size and position of the left, right, top and bottom units
164 _setSides: function(set) {
165 YAHOO.log('Setting side units', 'info', 'Layout');
166 var h1 = ((this._units.top) ? this._units.top.get('height') : 0),
167 h2 = ((this._units.bottom) ? this._units.bottom.get('height') : 0),
168 h = this._sizes.doc.h,
169 w = this._sizes.doc.w;
170 set = ((set === false) ? false : true);
173 h: h1, w: ((this._units.top) ? w : 0),
176 this._sizes.bottom = {
177 h: h2, w: ((this._units.bottom) ? w : 0)
180 var newH = (h - (h1 + h2));
183 h: newH, w: ((this._units.left) ? this._units.left.get('width') : 0)
185 this._sizes.right = {
186 h: newH, w: ((this._units.right) ? this._units.right.get('width') : 0),
187 l: ((this._units.right) ? (w - this._units.right.get('width')) : 0),
188 t: ((this._units.top) ? this._sizes.top.h : 0)
191 if (this._units.right && set) {
192 this._units.right.set('top', this._sizes.right.t);
193 if (!this._units.right._collapsing) {
194 this._units.right.set('left', this._sizes.right.l);
196 this._units.right.set('height', this._sizes.right.h, true);
198 if (this._units.left) {
199 this._sizes.left.l = 0;
200 if (this._units.top) {
201 this._sizes.left.t = this._sizes.top.h;
203 this._sizes.left.t = 0;
206 this._units.left.set('top', this._sizes.left.t);
207 this._units.left.set('height', this._sizes.left.h, true);
208 this._units.left.set('left', 0);
211 if (this._units.bottom) {
212 this._sizes.bottom.t = this._sizes.top.h + this._sizes.left.h;
214 this._units.bottom.set('top', this._sizes.bottom.t);
215 this._units.bottom.set('width', this._sizes.bottom.w, true);
218 if (this._units.top) {
220 this._units.top.set('width', this._sizes.top.w, true);
223 YAHOO.log('Setting sizes: (' + Lang.dump(this._sizes) + ')', 'info', 'Layout');
224 this._setCenter(set);
229 * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
230 * @description Used to set the size and position of the center unit
232 _setCenter: function(set) {
233 set = ((set === false) ? false : true);
234 var h = this._sizes.left.h;
235 var w = (this._sizes.doc.w - (this._sizes.left.w + this._sizes.right.w));
237 this._units.center.set('height', h, true);
238 this._units.center.set('width', w, true);
239 this._units.center.set('top', this._sizes.top.h);
240 this._units.center.set('left', this._sizes.left.w);
242 this._sizes.center = { h: h, w: w, t: this._sizes.top.h, l: this._sizes.left.w };
243 YAHOO.log('Setting Center size to: (' + h + ', ' + w + ')', 'info', 'Layout');
247 * @description Get a reference to the internal Layout Unit sizes object used to build the layout wireframe
248 * @return {Object} An object of the layout unit sizes
250 getSizes: function() {
254 * @method getUnitById
255 * @param {String} id The HTML element id of the unit
256 * @description Get the LayoutUnit by it's HTML id
257 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
259 getUnitById: function(id) {
260 return YAHOO.widget.LayoutUnit.getLayoutUnitById(id);
263 * @method getUnitByPosition
264 * @param {String} pos The position of the unit in this layout
265 * @description Get the LayoutUnit by it's position in this layout
266 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
268 getUnitByPosition: function(pos) {
270 pos = pos.toLowerCase();
271 if (this._units[pos]) {
272 return this._units[pos];
280 * @param {Object} unit The LayoutUnit that you want to remove
281 * @description Remove the unit from this layout and resize the layout.
283 removeUnit: function(unit) {
284 delete this._units[unit.get('position')];
289 * @param {Object} cfg The config for the LayoutUnit that you want to add
290 * @description Add a unit to this layout and if the layout is rendered, resize the layout.
291 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
293 addUnit: function(cfg) {
295 YAHOO.log('No position property passed', 'error', 'Layout');
298 if (this._units[cfg.position]) {
299 YAHOO.log('Position already exists', 'error', 'Layout');
302 YAHOO.log('Adding Unit at position: ' + cfg.position, 'info', 'Layout');
307 if (Dom.get(cfg.id)) {
308 element = Dom.get(cfg.id);
314 element = cfg.element;
318 el = document.createElement('div');
319 var id = Dom.generateId();
324 element = document.createElement('div');
326 Dom.addClass(element, 'yui-layout-wrap');
327 if (this.browser.ie && !this.browser.standardsMode) {
329 element.style.zoom = 1;
333 el.insertBefore(element, el.firstChild);
335 el.appendChild(element);
337 this._doc.appendChild(el);
339 var h = false, w = false;
342 h = parseInt(cfg.height, 10);
345 w = parseInt(cfg.width, 10);
348 YAHOO.lang.augmentObject(unitConfig, cfg); // break obj ref
350 unitConfig.parent = this;
351 unitConfig.wrap = element;
352 unitConfig.height = h;
353 unitConfig.width = w;
355 var unit = new YAHOO.widget.LayoutUnit(el, unitConfig);
357 unit.on('heightChange', this.resize, { unit: unit }, this);
358 unit.on('widthChange', this.resize, { unit: unit }, this);
359 unit.on('gutterChange', this.resize, { unit: unit }, this);
360 this._units[cfg.position] = unit;
362 if (this._rendered) {
370 * @method _createUnits
371 * @description Private method to create units from the config that was passed in.
373 _createUnits: function() {
374 var units = this.get('units');
375 for (var i in units) {
376 if (Lang.hasOwnProperty(units, i)) {
377 this.addUnit(units[i]);
383 * @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.
384 * @description Starts the chain of resize routines that will resize all the units.
385 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
387 resize: function(set, info) {
390 * If the event comes from an attribute and the value hasn't changed, don't process it.
393 if (ev && ev.prevValue && ev.newValue) {
394 if (ev.prevValue == ev.newValue) {
397 if (!info.unit.get('animate')) {
404 set = ((set === false) ? false : true);
406 var retVal = this.fireEvent('beforeResize');
407 if (retVal === false) {
410 if (this.browser.ie) {
412 Dom.removeClass(document.documentElement, 'yui-layout');
413 Dom.addClass(document.documentElement, 'yui-layout');
415 this.removeClass('yui-layout');
416 this.addClass('yui-layout');
420 this._setBodySize(set);
422 this.fireEvent('resize', { target: this, sizes: this._sizes, event: ev });
428 * @method _setupBodyElements
429 * @description Sets up the main doc element when using the body as the main element.
431 _setupBodyElements: function() {
432 this._doc = Dom.get('layout-doc');
434 this._doc = document.createElement('div');
435 this._doc.id = 'layout-doc';
436 if (document.body.firstChild) {
437 document.body.insertBefore(this._doc, document.body.firstChild);
439 document.body.appendChild(this._doc);
444 Event.on(window, 'resize', this.resize, this, true);
445 Dom.addClass(this._doc, 'yui-layout-doc');
449 * @method _setupElements
450 * @description Sets up the main doc element when not using the body as the main element.
452 _setupElements: function() {
453 this._doc = this.getElementsByClassName('yui-layout-doc')[0];
455 this._doc = document.createElement('div');
456 this.get('element').appendChild(this._doc);
460 Dom.addClass(this._doc, 'yui-layout-doc');
465 * @description Flag to determine if we are using the body as the root element.
472 * @description Reference to the root element
479 * @description The Layout class' initialization method
481 init: function(p_oElement, p_oAttributes) {
482 YAHOO.log('init', 'info', 'Layout');
486 Layout.superclass.init.call(this, p_oElement, p_oAttributes);
488 if (this.get('parent')) {
489 this._zIndex = this.get('parent')._zIndex + 10;
496 if (!Lang.isString(id)) {
497 id = Dom.generateId(id);
499 Layout._instances[id] = this;
503 * @description This method starts the render process, applying classnames and creating elements
504 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
507 YAHOO.log('Render', 'info', 'Layout');
509 var el = this.get('element');
510 if (el && el.tagName && (el.tagName.toLowerCase() == 'body')) {
512 Dom.addClass(document.body, 'yui-layout');
513 if (Dom.hasClass(document.body, 'yui-skin-sam')) {
514 //Move the class up so we can have a css chain
515 Dom.addClass(document.documentElement, 'yui-skin-sam');
516 Dom.removeClass(document.body, 'yui-skin-sam');
518 this._setupBodyElements();
520 this._isBody = false;
521 this.addClass('yui-layout');
522 this._setupElements();
525 this._rendered = true;
526 this.fireEvent('render');
533 * @description Stamps the root node with a secure classname for ease of use. Also sets the this.browser.standardsMode variable.
536 if (document.compatMode == 'CSS1Compat') {
537 this.browser.standardsMode = true;
539 if (window.location.href.toLowerCase().indexOf("https") === 0) {
540 Dom.addClass(document.documentElement, 'secure');
541 this.browser.secure = true;
546 * @method initAttributes
547 * @description Processes the config
549 initAttributes: function(attr) {
550 Layout.superclass.initAttributes.call(this, attr);
553 * @description An array of config definitions for the LayoutUnits to add to this layout
556 this.setAttributeConfig('units', {
558 validator: YAHOO.lang.isArray,
559 value: attr.units || []
563 * @attribute minHeight
564 * @description The minimum height in pixels
567 this.setAttributeConfig('minHeight', {
568 value: attr.minHeight || false,
569 validator: YAHOO.lang.isNumber
573 * @attribute minWidth
574 * @description The minimum width in pixels
577 this.setAttributeConfig('minWidth', {
578 value: attr.minWidth || false,
579 validator: YAHOO.lang.isNumber
584 * @description The height in pixels
587 this.setAttributeConfig('height', {
588 value: attr.height || false,
589 validator: YAHOO.lang.isNumber,
590 method: function(h) {
594 this.setStyle('height', h + 'px');
600 * @description The width in pixels
603 this.setAttributeConfig('width', {
604 value: attr.width || false,
605 validator: YAHOO.lang.isNumber,
606 method: function(w) {
610 this.setStyle('width', w + 'px');
616 * @description If this layout is to be used as a child of another Layout instance, this config will bind the resize events together.
617 * @type Object YAHOO.widget.Layout
619 this.setAttributeConfig('parent', {
621 value: attr.parent || false,
622 method: function(p) {
624 p.on('resize', this.resize, this, true);
631 * @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.
633 destroy: function() {
634 var par = this.get('parent');
636 par.removeListener('resize', this.resize, this, true);
638 Event.removeListener(window, 'resize', this.resize, this, true);
640 this.unsubscribeAll();
641 for (var u in this._units) {
642 if (Lang.hasOwnProperty(this._units, u)) {
643 if (this._units[u]) {
644 this._units[u].destroy(true);
649 Event.purgeElement(this.get('element'));
650 this.get('parentNode').removeChild(this.get('element'));
652 delete YAHOO.widget.Layout._instances[this.get('id')];
653 //Brutal Object Destroy
654 for (var i in this) {
655 if (Lang.hasOwnProperty(this, i)) {
667 * @description Returns a string representing the Layout.
670 toString: function() {
672 return 'Layout #' + this.get('id');
679 * @description Fired when this.resize is called
680 * @type YAHOO.util.CustomEvent
684 * @description Fired when the Resize Utility for a Unit fires it's startResize Event.
685 * @type YAHOO.util.CustomEvent
688 * @event beforeResize
689 * @description Fires at the beginning of the resize method. If you return false, the resize is cancelled.
690 * @type YAHOO.util.CustomEvent
694 * @description Fired after the render method completes.
695 * @type YAHOO.util.CustomEvent
698 YAHOO.widget.Layout = Layout;
701 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
702 * @namespace YAHOO.widget
703 * @requires yahoo, dom, element, event, layout
704 * @optional animation, dragdrop, selector
707 var Dom = YAHOO.util.Dom,
708 Sel = YAHOO.util.Selector,
709 Event = YAHOO.util.Event,
715 * @extends YAHOO.util.Element
716 * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
717 * @param {String/HTMLElement} el The element to make a unit.
718 * @param {Object} attrs Object liternal containing configuration parameters.
721 var LayoutUnit = function(el, config) {
725 attributes: config || {}
728 LayoutUnit.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
734 * @property _instances
735 * @description Internal hash table for all layout unit instances
738 LayoutUnit._instances = {};
741 * @method getLayoutUnitById
742 * @description Get's a layout unit object by the HTML id of the element associated with the Layout Unit object.
743 * @return {Object} The Layout Object
745 LayoutUnit.getLayoutUnitById = function(id) {
746 if (LayoutUnit._instances[id]) {
747 return LayoutUnit._instances[id];
752 YAHOO.extend(LayoutUnit, YAHOO.util.Element, {
754 * @property STR_CLOSE
755 * @description String used for close button title
758 STR_CLOSE: 'Click to close this pane.',
760 * @property STR_COLLAPSE
761 * @description String used for collapse button title
764 STR_COLLAPSE: 'Click to collapse this pane.',
766 * @property STR_EXPAND
767 * @description String used for expand button title
770 STR_EXPAND: 'Click to expand this pane.',
772 * The class name applied to dynamic tabs while loading.
773 * @property LOADING_CLASSNAME
775 * @default "disabled"
777 LOADING_CLASSNAME: 'loading',
780 * @description A modified version of the YAHOO.env.ua object
787 * @description A collection of the current sizes of the contents of this Layout Unit
794 * @description A reference to the Animation instance used by this LayouUnit
795 * @type YAHOO.util.Anim
801 * @description A reference to the Resize instance used by this LayoutUnit
802 * @type YAHOO.util.Resize
808 * @description A reference to the clip element used when collapsing the unit
815 * @description A simple hash table used to store the gutter to apply to the Unit
821 * @description A reference to the HTML element used for the Header
827 * @description A reference to the HTML element used for the body
833 * @description A reference to the HTML element used for the footer
839 * @property _collapsed
840 * @description Flag to determine if the unit is collapsed or not.
846 * @property _collapsing
847 * @description A flag set while the unit is being collapsed, used so we don't fire events while animating the size
853 * @property _lastWidth
854 * @description A holder for the last known width of the unit
860 * @property _lastHeight
861 * @description A holder for the last known height of the unit
868 * @description A holder for the last known top of the unit
874 * @property _lastLeft
875 * @description A holder for the last known left of the unit
881 * @property _lastScroll
882 * @description A holder for the last known scroll state of the unit
888 * @property _lastCenetrScroll
889 * @description A holder for the last known scroll state of the center unit
892 _lastCenterScroll: null,
895 * @property _lastScrollTop
896 * @description A holder for the last known scrollTop state of the unit
899 _lastScrollTop: null,
902 * @description Resize either the unit or it's clipped state, also updating the box inside
903 * @param {Boolean} force This will force full calculations even when the unit is collapsed
904 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
906 resize: function(force) {
907 YAHOO.log('Resize', 'info', 'LayoutUnit');
908 var retVal = this.fireEvent('beforeResize');
909 if (retVal === false) {
912 if (!this._collapsing || (force === true)) {
913 var scroll = this.get('scroll');
914 this.set('scroll', false);
917 var hd = this._getBoxSize(this.header),
918 ft = this._getBoxSize(this.footer),
919 box = [this.get('height'), this.get('width')];
921 var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
922 nw = box[1] - (this._gutter.left + this._gutter.right);
924 var wrapH = (nh + (hd[0] + ft[0])),
927 if (this._collapsed && !this._collapsing) {
928 this._setHeight(this._clip, wrapH);
929 this._setWidth(this._clip, wrapW);
930 Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
931 Dom.setStyle(this._clip, 'left', this.get('left') + this._gutter.left + 'px');
932 } else if (!this._collapsed || (this._collapsed && this._collapsing)) {
933 wrapH = this._setHeight(this.get('wrap'), wrapH);
934 wrapW = this._setWidth(this.get('wrap'), wrapW);
935 this._sizes.wrap.h = wrapH;
936 this._sizes.wrap.w = wrapW;
938 Dom.setStyle(this.get('wrap'), 'top', this._gutter.top + 'px');
939 Dom.setStyle(this.get('wrap'), 'left', this._gutter.left + 'px');
941 this._sizes.header.w = this._setWidth(this.header, wrapW);
942 this._sizes.header.h = hd[0];
944 this._sizes.footer.w = this._setWidth(this.footer, wrapW);
945 this._sizes.footer.h = ft[0];
947 Dom.setStyle(this.footer, 'bottom', '0px');
949 this._sizes.body.h = this._setHeight(this.body, (wrapH - (hd[0] + ft[0])));
950 this._sizes.body.w =this._setWidth(this.body, wrapW);
951 Dom.setStyle(this.body, 'top', hd[0] + 'px');
953 this.set('scroll', scroll);
954 this.fireEvent('resize');
962 * @description Sets the width of the element based on the border size of the element.
963 * @param {HTMLElement} el The HTMLElement to have it's width set
964 * @param {Number} w The width that you want it the element set to
965 * @return {Number} The new width, fixed for borders and IE QuirksMode
967 _setWidth: function(el, w) {
969 var b = this._getBorderSizes(el);
970 w = (w - (b[1] + b[3]));
971 w = this._fixQuirks(el, w, 'w');
975 Dom.setStyle(el, 'width', w + 'px');
982 * @description Sets the height of the element based on the border size of the element.
983 * @param {HTMLElement} el The HTMLElement to have it's height set
984 * @param {Number} h The height that you want it the element set to
985 * @return {Number} The new height, fixed for borders and IE QuirksMode
987 _setHeight: function(el, h) {
989 var b = this._getBorderSizes(el);
990 h = (h - (b[0] + b[2]));
991 h = this._fixQuirks(el, h, 'h');
995 Dom.setStyle(el, 'height', h + 'px');
1001 * @method _fixQuirks
1002 * @description Fixes the box calculations for IE in QuirksMode
1003 * @param {HTMLElement} el The HTMLElement to set the dimension on
1004 * @param {Number} dim The number of the dimension to fix
1005 * @param {String} side The dimension (h or w) to fix. Defaults to h
1006 * @return {Number} The fixed dimension
1008 _fixQuirks: function(el, dim, side) {
1014 if ((this.browser.ie < 8) && !this.browser.standardsMode) {
1015 //Internet Explorer - Quirks Mode
1016 var b = this._getBorderSizes(el),
1017 bp = this._getBorderSizes(el.parentNode);
1018 if ((b[i1] === 0) && (b[i2] === 0)) { //No Borders, check parent
1019 if ((bp[i1] !== 0) && (bp[i2] !== 0)) { //Parent has Borders
1020 dim = (dim - (bp[i1] + bp[i2]));
1023 if ((bp[i1] === 0) && (bp[i2] === 0)) {
1024 dim = (dim + (b[i1] + b[i2]));
1032 * @method _getBoxSize
1033 * @description Get's the elements clientHeight and clientWidth plus the size of the borders
1034 * @param {HTMLElement} el The HTMLElement to get the size of
1035 * @return {Array} An array of height and width
1037 _getBoxSize: function(el) {
1040 if (this.browser.ie && !this.browser.standardsMode) {
1043 var b = this._getBorderSizes(el);
1044 size[0] = el.clientHeight + (b[0] + b[2]);
1045 size[1] = el.clientWidth + (b[1] + b[3]);
1051 * @method _getBorderSizes
1052 * @description Get the CSS border size of the element passed.
1053 * @param {HTMLElement} el The element to get the border size of
1054 * @return {Array} An array of the top, right, bottom, left borders.
1056 _getBorderSizes: function(el) {
1058 el = el || this.get('element');
1059 if (this.browser.ie && !this.browser.standardsMode) {
1062 s[0] = parseInt(Dom.getStyle(el, 'borderTopWidth'), 10);
1063 s[1] = parseInt(Dom.getStyle(el, 'borderRightWidth'), 10);
1064 s[2] = parseInt(Dom.getStyle(el, 'borderBottomWidth'), 10);
1065 s[3] = parseInt(Dom.getStyle(el, 'borderLeftWidth'), 10);
1067 //IE will return NaN on these if they are set to auto, we'll set them to 0
1068 for (var i = 0; i < s.length; i++) {
1077 * @method _createClip
1078 * @description Create the clip element used when the Unit is collapsed
1080 _createClip: function() {
1082 this._clip = document.createElement('div');
1083 this._clip.className = 'yui-layout-clip yui-layout-clip-' + this.get('position');
1084 this._clip.innerHTML = '<div class="collapse"></div>';
1085 var c = this._clip.firstChild;
1086 c.title = this.STR_EXPAND;
1087 Event.on(c, 'click', this.expand, this, true);
1088 this.get('element').parentNode.appendChild(this._clip);
1093 * @method _toggleClip
1094 * @description Toggle th current state of the Clip element and set it's height, width and position
1096 _toggleClip: function() {
1097 if (!this._collapsed) {
1099 var hd = this._getBoxSize(this.header),
1100 ft = this._getBoxSize(this.footer),
1101 box = [this.get('height'), this.get('width')];
1104 var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
1105 nw = box[1] - (this._gutter.left + this._gutter.right),
1106 wrapH = (nh + (hd[0] + ft[0]));
1108 switch (this.get('position')) {
1111 this._setWidth(this._clip, nw);
1112 this._setHeight(this._clip, this.get('collapseSize'));
1113 Dom.setStyle(this._clip, 'left', (this._lastLeft + this._gutter.left) + 'px');
1114 if (this.get('position') == 'bottom') {
1115 Dom.setStyle(this._clip, 'top', ((this._lastTop + this._lastHeight) - (this.get('collapseSize') - this._gutter.top)) + 'px');
1117 Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
1122 this._setWidth(this._clip, this.get('collapseSize'));
1123 this._setHeight(this._clip, wrapH);
1124 Dom.setStyle(this._clip, 'top', (this.get('top') + this._gutter.top) + 'px');
1125 if (this.get('position') == 'right') {
1126 Dom.setStyle(this._clip, 'left', (((this._lastLeft + this._lastWidth) - this.get('collapseSize')) - this._gutter.left) + 'px');
1128 Dom.setStyle(this._clip, 'left', (this.get('left') + this._gutter.left) + 'px');
1133 Dom.setStyle(this._clip, 'display', 'block');
1134 this.setStyle('display', 'none');
1137 Dom.setStyle(this._clip, 'display', 'none');
1142 * @description Get a reference to the internal sizes object for this unit
1143 * @return {Object} An object of the sizes used for calculations
1145 getSizes: function() {
1150 * @description Toggles the Unit, replacing it with a clipped version.
1151 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1153 toggle: function() {
1154 if (this._collapsed) {
1163 * @description Expand the Unit if it is collapsed.
1164 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1166 expand: function() {
1167 if (!this._collapsed) {
1170 var retVal = this.fireEvent('beforeExpand');
1171 if (retVal === false) {
1175 this._collapsing = true;
1176 this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1179 this.setStyle('display', 'none');
1182 switch (this.get('position')) {
1185 this.set('width', this._lastWidth, true);
1186 this.setStyle('width', this._lastWidth + 'px');
1187 this.get('parent').resize(false);
1188 s = this.get('parent').getSizes()[this.get('position')];
1189 this.set('height', s.h, true);
1196 if (this.get('position') == 'left') {
1197 attr.left.from = (left - s.w);
1198 this.setStyle('left', (left - s.w) + 'px');
1203 this.set('height', this._lastHeight, true);
1204 this.setStyle('height', this._lastHeight + 'px');
1205 this.get('parent').resize(false);
1206 s = this.get('parent').getSizes()[this.get('position')];
1207 this.set('width', s.w, true);
1214 if (this.get('position') == 'top') {
1215 this.setStyle('top', (top - s.h) + 'px');
1216 attr.top.from = (top - s.h);
1221 this._anim.attributes = attr;
1222 var exStart = function() {
1223 this.setStyle('display', 'block');
1225 this._anim.onStart.unsubscribe(exStart, this, true);
1227 var expand = function() {
1228 this._collapsing = false;
1229 this.setStyle('zIndex', this.get('parent')._zIndex);
1230 this.set('width', this._lastWidth);
1231 this.set('height', this._lastHeight);
1232 this._collapsed = false;
1234 this.set('scroll', this._lastScroll);
1235 if (this._lastScrollTop > 0) {
1236 this.body.scrollTop = this._lastScrollTop;
1238 this._anim.onComplete.unsubscribe(expand, this, true);
1239 this.fireEvent('expand');
1241 this._anim.onStart.subscribe(exStart, this, true);
1242 this._anim.onComplete.subscribe(expand, this, true);
1243 this._anim.animate();
1246 this._collapsing = false;
1248 this._collapsed = false;
1249 this.setStyle('zIndex', this.get('parent')._zIndex);
1250 this.setStyle('display', 'block');
1251 this.set('width', this._lastWidth);
1252 this.set('height', this._lastHeight);
1254 this.set('scroll', this._lastScroll);
1255 if (this._lastScrollTop > 0) {
1256 this.body.scrollTop = this._lastScrollTop;
1258 this.fireEvent('expand');
1264 * @description Collapse the Unit if it is not collapsed.
1265 * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
1267 collapse: function() {
1268 if (this._collapsed) {
1271 var retValue = this.fireEvent('beforeCollapse');
1272 if (retValue === false) {
1278 this._collapsing = true;
1279 var w = this.get('width'),
1280 h = this.get('height'),
1282 this._lastWidth = w;
1283 this._lastHeight = h;
1284 this._lastScroll = this.get('scroll');
1285 this._lastScrollTop = this.body.scrollTop;
1286 this.set('scroll', false, true);
1287 this._lastLeft = parseInt(this.get('element').style.left, 10);
1288 this._lastTop = parseInt(this.get('element').style.top, 10);
1289 if (isNaN(this._lastTop)) {
1293 if (isNaN(this._lastLeft)) {
1295 this.set('left', 0);
1297 this.setStyle('zIndex', this.get('parent')._zIndex + 1);
1298 var pos = this.get('position');
1303 this.set('height', (this.get('collapseSize') + (this._gutter.top + this._gutter.bottom)));
1306 to: (this.get('top') - h)
1309 if (pos == 'bottom') {
1310 attr.top.to = (this.get('top') + h);
1315 this.set('width', (this.get('collapseSize') + (this._gutter.left + this._gutter.right)));
1318 to: -(this._lastWidth)
1321 if (pos == 'right') {
1323 to: (this.get('left') + w)
1329 this._anim.attributes = attr;
1330 var collapse = function() {
1331 this._collapsing = false;
1333 this.setStyle('zIndex', this.get('parent')._zIndex);
1334 this._collapsed = true;
1335 this.get('parent').resize();
1336 this._anim.onComplete.unsubscribe(collapse, this, true);
1337 this.fireEvent('collapse');
1339 this._anim.onComplete.subscribe(collapse, this, true);
1340 this._anim.animate();
1342 this._collapsing = false;
1343 this.setStyle('display', 'none');
1345 this.setStyle('zIndex', this.get('parent')._zIndex);
1346 this.get('parent').resize();
1347 this._collapsed = true;
1348 this.fireEvent('collapse');
1354 * @description Close the unit, removing it from the parent Layout.
1355 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
1358 this.setStyle('display', 'none');
1359 this.get('parent').removeUnit(this);
1360 this.fireEvent('close');
1362 this._clip.parentNode.removeChild(this._clip);
1365 return this.get('parent');
1368 * @property loadHandler
1369 * @description Callback method for the YUI Connection Manager used for load the body using AJAX
1373 success: function(o) {
1374 this.body.innerHTML = o.responseText;
1377 failure: function(o) {
1381 * @property dataConnection
1382 * @description YUI Connection Manager handler
1385 dataConnection: null,
1388 * @property _loading
1389 * @description During the loading process this variable will be true
1394 * @method loadContent
1395 * @description Loading the content of the unit using the connection manager
1396 * @return {object} YUI Connection Manager handler
1398 loadContent: function() {
1399 // load dynamic content unless already loading or loaded and caching
1400 if (YAHOO.util.Connect && this.get('dataSrc') && !this._loading && !this.get('dataLoaded')) {
1401 this._loading = true;
1402 Dom.addClass(this.body, this.LOADING_CLASSNAME);
1403 this.dataConnection = YAHOO.util.Connect.asyncRequest(
1404 this.get('loadMethod'),
1405 this.get('dataSrc'),
1407 success: function(o) {
1408 this.loadHandler.success.call(this, o);
1409 this.set('dataLoaded', true);
1410 this.dataConnection = null;
1411 Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1412 this._loading = false;
1413 this.fireEvent('load');
1415 failure: function(o) {
1416 this.loadHandler.failure.call(this, o);
1417 this.dataConnection = null;
1418 Dom.removeClass(this.body, this.LOADING_CLASSNAME);
1419 this._loading = false;
1420 this.fireEvent('loadError', { error: o });
1423 timeout: this.get('dataTimeout')
1426 return this.dataConnection;
1433 * @description The initalization method inherited from Element.
1435 init: function(p_oElement, p_oAttributes) {
1436 YAHOO.log('init', 'info', 'LayoutUnit');
1462 LayoutUnit.superclass.init.call(this, p_oElement, p_oAttributes);
1464 this.browser = this.get('parent').browser;
1466 var id = p_oElement;
1467 if (!Lang.isString(id)) {
1468 id = Dom.generateId(id);
1470 LayoutUnit._instances[id] = this;
1472 this.setStyle('position', 'absolute');
1474 this.addClass('yui-layout-unit');
1475 this.addClass('yui-layout-unit-' + this.get('position'));
1478 var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1480 this.header = header;
1482 var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1486 var footer = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1488 this.footer = footer;
1491 this.on('contentChange', this.resize, this, true);
1492 this._lastScrollTop = 0;
1494 this.set('animate', this.get('animate'));
1498 * @method initAttributes
1499 * @description Processes the config
1501 initAttributes: function(attr) {
1502 LayoutUnit.superclass.initAttributes.call(this, attr);
1507 * @description A reference to the wrap element
1510 this.setAttributeConfig('wrap', {
1511 value: attr.wrap || null,
1512 method: function(w) {
1514 var id = Dom.generateId(w);
1515 LayoutUnit._instances[id] = this;
1521 * @description Set this option to true if you want the LayoutUnit to fix the first layer of YUI CSS Grids (margins)
1524 this.setAttributeConfig('grids', {
1525 value: attr.grids || false
1530 * @description The current top positioning of the Unit
1533 this.setAttributeConfig('top', {
1534 value: attr.top || 0,
1535 validator: Lang.isNumber,
1536 method: function(t) {
1537 if (!this._collapsing) {
1538 this.setStyle('top', t + 'px');
1545 * @description The current left position of the Unit
1548 this.setAttributeConfig('left', {
1549 value: attr.left || 0,
1550 validator: Lang.isNumber,
1551 method: function(l) {
1552 if (!this._collapsing) {
1553 this.setStyle('left', l + 'px');
1559 * @attribute minWidth
1560 * @description The minWidth parameter passed to the Resize Utility
1563 this.setAttributeConfig('minWidth', {
1564 value: attr.minWidth || false,
1565 method: function(v) {
1567 this._resize.set('minWidth', v);
1570 validator: YAHOO.lang.isNumber
1574 * @attribute maxWidth
1575 * @description The maxWidth parameter passed to the Resize Utility
1578 this.setAttributeConfig('maxWidth', {
1579 value: attr.maxWidth || false,
1580 method: function(v) {
1582 this._resize.set('maxWidth', v);
1585 validator: YAHOO.lang.isNumber
1589 * @attribute minHeight
1590 * @description The minHeight parameter passed to the Resize Utility
1593 this.setAttributeConfig('minHeight', {
1594 value: attr.minHeight || false,
1595 method: function(v) {
1597 this._resize.set('minHeight', v);
1600 validator: YAHOO.lang.isNumber
1604 * @attribute maxHeight
1605 * @description The maxHeight parameter passed to the Resize Utility
1608 this.setAttributeConfig('maxHeight', {
1609 value: attr.maxHeight || false,
1610 method: function(v) {
1612 this._resize.set('maxHeight', v);
1615 validator: YAHOO.lang.isNumber
1620 * @description The height of the Unit
1623 this.setAttributeConfig('height', {
1625 validator: Lang.isNumber,
1626 method: function(h) {
1627 if (!this._collapsing) {
1631 this.setStyle('height', h + 'px');
1638 * @description The width of the Unit
1641 this.setAttributeConfig('width', {
1643 validator: Lang.isNumber,
1644 method: function(w) {
1645 if (!this._collapsing) {
1649 this.setStyle('width', w + 'px');
1655 * @description The CSS zIndex to give to the unit, so you can have overlapping elements such as menus in a unit.
1658 this.setAttributeConfig('zIndex', {
1659 value: attr.zIndex || false,
1660 method: function(z) {
1661 this.setStyle('zIndex', z);
1665 * @attribute position
1666 * @description The position (top, right, bottom, left or center) of the Unit in the Layout
1669 this.setAttributeConfig('position', {
1670 value: attr.position
1674 * @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)
1677 this.setAttributeConfig('gutter', {
1678 value: attr.gutter || 0,
1679 validator: YAHOO.lang.isString,
1680 method: function(gutter) {
1681 var p = gutter.split(' ');
1683 this._gutter.top = parseInt(p[0], 10);
1685 this._gutter.right = parseInt(p[1], 10);
1687 this._gutter.right = this._gutter.top;
1690 this._gutter.bottom = parseInt(p[2], 10);
1692 this._gutter.bottom = this._gutter.top;
1695 this._gutter.left = parseInt(p[3], 10);
1697 this._gutter.left = this._gutter.right;
1699 this._gutter.left = this._gutter.top;
1706 * @description The parent Layout that we are assigned to
1707 * @type {Object} YAHOO.widget.Layout
1709 this.setAttributeConfig('parent', {
1711 value: attr.parent || false,
1712 method: function(p) {
1714 p.on('resize', this.resize, this, true);
1720 * @attribute collapseSize
1721 * @description The pixel size of the Clip that we will collapse to
1724 this.setAttributeConfig('collapseSize', {
1725 value: attr.collapseSize || 25,
1726 validator: YAHOO.lang.isNumber
1729 * @attribute duration
1730 * @description The duration to give the Animation Utility when animating the opening and closing of Units
1732 this.setAttributeConfig('duration', {
1733 value: attr.duration || 0.5
1737 * @description The Animation Easing to apply to the Animation instance for this unit.
1739 this.setAttributeConfig('easing', {
1740 value: attr.easing || ((YAHOO.util && YAHOO.util.Easing) ? YAHOO.util.Easing.BounceIn : 'false')
1743 * @attribute animate
1744 * @description Use animation to collapse/expand the unit
1747 this.setAttributeConfig('animate', {
1748 value: ((attr.animate === false) ? false : true),
1749 validator: function() {
1751 if (YAHOO.util.Anim) {
1756 method: function(anim) {
1758 this._anim = new YAHOO.util.Anim(this.get('element'), {}, this.get('duration'), this.get('easing'));
1766 * @description The text to use as the Header of the Unit
1768 this.setAttributeConfig('header', {
1769 value: attr.header || false,
1770 method: function(txt) {
1771 if (txt === false) {
1774 Dom.addClass(this.body, 'yui-layout-bd-nohd');
1775 this.header.parentNode.removeChild(this.header);
1780 var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
1782 header = this._createHeader();
1784 this.header = header;
1786 var h = this.header.getElementsByTagName('h2')[0];
1788 h = document.createElement('h2');
1789 this.header.appendChild(h);
1793 Dom.removeClass(this.body, 'yui-layout-bd-nohd');
1796 this.fireEvent('contentChange', { target: 'header' });
1801 * @description Use the proxy config setting for the Resize Utility
1804 this.setAttributeConfig('proxy', {
1806 value: ((attr.proxy === false) ? false : true)
1810 * @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.
1812 this.setAttributeConfig('body', {
1813 value: attr.body || false,
1814 method: function(content) {
1816 var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
1820 body = document.createElement('div');
1821 body.className = 'yui-layout-bd';
1823 this.get('wrap').appendChild(body);
1827 Dom.addClass(this.body, 'yui-layout-bd-nohd');
1829 Dom.addClass(this.body, 'yui-layout-bd-noft');
1833 if (Lang.isString(content)) {
1834 el = Dom.get(content);
1835 } else if (content && content.tagName) {
1839 var id = Dom.generateId(el);
1840 LayoutUnit._instances[id] = this;
1841 this.body.appendChild(el);
1843 this.body.innerHTML = content;
1848 this.fireEvent('contentChange', { target: 'body' });
1854 * @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.
1856 this.setAttributeConfig('footer', {
1857 value: attr.footer || false,
1858 method: function(content) {
1859 if (content === false) {
1862 Dom.addClass(this.body, 'yui-layout-bd-noft');
1863 this.footer.parentNode.removeChild(this.footer);
1868 var ft = this.getElementsByClassName('yui-layout-ft', 'div')[0];
1870 ft = document.createElement('div');
1871 ft.className = 'yui-layout-ft';
1873 this.get('wrap').appendChild(ft);
1879 if (Lang.isString(content)) {
1880 el = Dom.get(content);
1881 } else if (content && content.tagName) {
1885 this.footer.appendChild(el);
1887 this.footer.innerHTML = content;
1889 Dom.removeClass(this.body, 'yui-layout-bd-noft');
1891 this.fireEvent('contentChange', { target: 'footer' });
1896 * @description Adds a close icon to the unit
1898 this.setAttributeConfig('close', {
1899 value: attr.close || false,
1900 method: function(close) {
1901 //Position Center doesn't get this
1902 if (this.get('position') == 'center') {
1903 YAHOO.log('Position center unit cannot have close', 'error', 'LayoutUnit');
1906 if (!this.header && close) {
1907 this._createHeader();
1909 var c = Dom.getElementsByClassName('close', 'div', this.header)[0];
1911 //Force some header text if there isn't any
1912 if (!this.get('header')) {
1913 this.set('header', ' ');
1916 c = document.createElement('div');
1917 c.className = 'close';
1918 this.header.appendChild(c);
1919 Event.on(c, 'click', this.close, this, true);
1921 c.title = this.STR_CLOSE;
1922 } else if (c && c.parentNode) {
1923 Event.purgeElement(c);
1924 c.parentNode.removeChild(c);
1926 this._configs.close.value = close;
1927 this.set('collapse', this.get('collapse')); //Reset so we get the right classnames
1932 * @attribute collapse
1933 * @description Adds a collapse icon to the unit
1935 this.setAttributeConfig('collapse', {
1936 value: attr.collapse || false,
1937 method: function(collapse) {
1938 //Position Center doesn't get this
1939 if (this.get('position') == 'center') {
1940 YAHOO.log('Position center unit cannot have collapse', 'error', 'LayoutUnit');
1943 if (!this.header && collapse) {
1944 this._createHeader();
1946 var c = Dom.getElementsByClassName('collapse', 'div', this.header)[0];
1948 //Force some header text if there isn't any
1949 if (!this.get('header')) {
1950 this.set('header', ' ');
1953 c = document.createElement('div');
1954 this.header.appendChild(c);
1955 Event.on(c, 'click', this.collapse, this, true);
1957 c.title = this.STR_COLLAPSE;
1958 c.className = 'collapse' + ((this.get('close')) ? ' collapse-close' : '');
1959 } else if (c && c.parentNode) {
1960 Event.purgeElement(c);
1961 c.parentNode.removeChild(c);
1967 * @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.
1968 * @type Boolean/Null
1971 this.setAttributeConfig('scroll', {
1972 value: (((attr.scroll === true) || (attr.scroll === false) || (attr.scroll === null)) ? attr.scroll : false),
1973 method: function(scroll) {
1974 if ((scroll === false) && !this._collapsed) { //Removing scroll bar
1976 if (this.body.scrollTop > 0) {
1977 this._lastScrollTop = this.body.scrollTop;
1982 if (scroll === true) {
1983 this.addClass('yui-layout-scroll');
1984 this.removeClass('yui-layout-noscroll');
1985 if (this._lastScrollTop > 0) {
1987 this.body.scrollTop = this._lastScrollTop;
1990 } else if (scroll === false) {
1991 this.removeClass('yui-layout-scroll');
1992 this.addClass('yui-layout-noscroll');
1993 } else if (scroll === null) {
1994 this.removeClass('yui-layout-scroll');
1995 this.removeClass('yui-layout-noscroll');
2001 * @description Config option to pass to the Resize Utility
2003 this.setAttributeConfig('hover', {
2005 value: attr.hover || false,
2006 validator: YAHOO.lang.isBoolean
2009 * @attribute useShim
2010 * @description Config option to pass to the Resize Utility
2012 this.setAttributeConfig('useShim', {
2013 value: attr.useShim || false,
2014 validator: YAHOO.lang.isBoolean,
2015 method: function(u) {
2017 this._resize.set('useShim', u);
2023 * @description Should a Resize instance be added to this unit
2026 this.setAttributeConfig('resize', {
2027 value: attr.resize || false,
2028 validator: function(r) {
2029 if (YAHOO.util && YAHOO.util.Resize) {
2034 method: function(resize) {
2035 if (resize && !this._resize) {
2036 //Position Center doesn't get this
2037 if (this.get('position') == 'center') {
2038 YAHOO.log('Position center unit cannot have resize', 'error', 'LayoutUnit');
2041 var handle = false; //To catch center
2042 switch (this.get('position')) {
2057 this.setStyle('position', 'absolute'); //Make sure Resize get's a position
2060 this._resize = new YAHOO.util.Resize(this.get('element'), {
2061 proxy: this.get('proxy'),
2062 hover: this.get('hover'),
2066 minWidth: this.get('minWidth'),
2067 maxWidth: this.get('maxWidth'),
2068 minHeight: this.get('minHeight'),
2069 maxHeight: this.get('maxHeight'),
2070 height: this.get('height'),
2071 width: this.get('width'),
2073 useShim: this.get('useShim'),
2077 this._resize._handles[handle].innerHTML = '<div class="yui-layout-resize-knob"></div>';
2079 if (this.get('proxy')) {
2080 var proxy = this._resize.getProxyEl();
2081 proxy.innerHTML = '<div class="yui-layout-handle-' + handle + '"></div>';
2083 this._resize.on('startResize', function(ev) {
2084 this._lastScroll = this.get('scroll');
2085 this.set('scroll', false);
2086 if (this.get('parent')) {
2087 this.get('parent').fireEvent('startResize');
2088 var c = this.get('parent').getUnitByPosition('center');
2089 this._lastCenterScroll = c.get('scroll');
2090 c.addClass(this._resize.CSS_RESIZING);
2091 c.set('scroll', false);
2093 this.fireEvent('startResize');
2095 this._resize.on('resize', function(ev) {
2096 this.set('height', ev.height);
2097 this.set('width', ev.width);
2099 this._resize.on('endResize', function(ev) {
2100 this.set('scroll', this._lastScroll);
2101 if (this.get('parent')) {
2102 var c = this.get('parent').getUnitByPosition('center');
2103 c.set('scroll', this._lastCenterScroll);
2104 c.removeClass(this._resize.CSS_RESIZING);
2107 this.fireEvent('endResize');
2112 this._resize.destroy();
2118 * The unit data source, used for loading content dynamically.
2119 * @attribute dataSrc
2122 this.setAttributeConfig('dataSrc', {
2126 * The method to use for the data request.
2127 * @attribute loadMethod
2131 this.setAttributeConfig('loadMethod', {
2132 value: attr.loadMethod || 'GET',
2133 validator: YAHOO.lang.isString
2136 * Whether or not any data has been loaded from the server.
2137 * @attribute dataLoaded
2140 this.setAttributeConfig('dataLoaded', {
2142 validator: YAHOO.lang.isBoolean,
2146 * Number if milliseconds before aborting and calling failure handler.
2147 * @attribute dataTimeout
2151 this.setAttributeConfig('dataTimeout', {
2152 value: attr.dataTimeout || null,
2153 validator: YAHOO.lang.isNumber
2158 * @method _cleanGrids
2159 * @description This method attempts to clean up the first level of the YUI CSS Grids, YAHOO.util.Selector is required for this operation.
2161 _cleanGrids: function() {
2162 if (this.get('grids')) {
2163 var b = Sel.query('div.yui-b', this.body, true);
2165 Dom.removeClass(b, 'yui-b');
2167 Event.onAvailable('yui-main', function() {
2168 Dom.setStyle(Sel.query('#yui-main'), 'margin-left', '0');
2169 Dom.setStyle(Sel.query('#yui-main'), 'margin-right', '0');
2175 * @method _createHeader
2176 * @description Creates the HTMLElement for the header
2177 * @return {HTMLElement} The new HTMLElement
2179 _createHeader: function() {
2180 var header = document.createElement('div');
2181 header.className = 'yui-layout-hd';
2182 if (this.get('firstChild')) {
2183 this.get('wrap').insertBefore(header, this.get('wrap').firstChild);
2185 this.get('wrap').appendChild(header);
2187 this.header = header;
2192 * @param {Boolean} force Don't report to the parent, because we are being called from the parent.
2193 * @description Removes this unit from the parent and cleans up after itself.
2194 * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
2196 destroy: function(force) {
2198 this._resize.destroy();
2200 var par = this.get('parent');
2202 this.setStyle('display', 'none');
2204 this._clip.parentNode.removeChild(this._clip);
2209 par.removeUnit(this);
2213 par.removeListener('resize', this.resize, this, true);
2215 this.unsubscribeAll();
2216 Event.purgeElement(this.get('element'));
2217 this.get('parentNode').removeChild(this.get('element'));
2219 delete YAHOO.widget.LayoutUnit._instances[this.get('id')];
2220 //Brutal Object Destroy
2221 for (var i in this) {
2222 if (Lang.hasOwnProperty(this, i)) {
2232 * @description Returns a string representing the LayoutUnit.
2235 toString: function() {
2237 return 'LayoutUnit #' + this.get('id') + ' (' + this.get('position') + ')';
2239 return 'LayoutUnit';
2243 * @description Fired when this.resize is called
2244 * @type YAHOO.util.CustomEvent
2247 * @event startResize
2248 * @description Fired when the Resize Utility fires it's startResize Event.
2249 * @type YAHOO.util.CustomEvent
2253 * @description Fired when the Resize Utility fires it's endResize Event.
2254 * @type YAHOO.util.CustomEvent
2257 * @event beforeResize
2258 * @description Fired at the beginning of the resize method. If you return false, the resize is cancelled.
2259 * @type YAHOO.util.CustomEvent
2262 * @event contentChange
2263 * @description Fired when the content in the header, body or footer is changed via the API
2264 * @type YAHOO.util.CustomEvent
2268 * @description Fired when the unit is closed
2269 * @type YAHOO.util.CustomEvent
2272 * @event beforeCollapse
2273 * @description Fired before the unit is collapsed. If you return false, the collapse is cancelled.
2274 * @type YAHOO.util.CustomEvent
2278 * @description Fired when the unit is collapsed
2279 * @type YAHOO.util.CustomEvent
2283 * @description Fired when the unit is exanded
2284 * @type YAHOO.util.CustomEvent
2287 * @event beforeExpand
2288 * @description Fired before the unit is exanded. If you return false, the collapse is cancelled.
2289 * @type YAHOO.util.CustomEvent
2293 * @description Fired when data is loaded via the dataSrc config.
2294 * @type YAHOO.util.CustomEvent
2298 * @description Fired when an error occurs loading data via the dataSrc config. Error message is passed as argument to this event.
2299 * @type YAHOO.util.CustomEvent
2303 YAHOO.widget.LayoutUnit = LayoutUnit;
2305 YAHOO.register("layout", YAHOO.widget.Layout, {version: "2.8.0r4", build: "2449"});