jQuery UI Layout Plug-in
| |||||
If you find Layout useful and want to support its development...
Updated Oct 29, 2012 |
This is a temporary page to collect new features added in the Release Candidate versions for UI Layout 1.3.0. I will add all the new features I can remember here for each RC version. When 1.3.0 Final is released, this information will be merged into the website documentation.
Latest Version: 1.3.0 RC-30.79 jquery.layout-1.3.0.rc30.79.js
-or- jquery.layout-1.3.0.rc30.79.min.js
-or- If you're not already using a 1.3.0.RC version of Layout, also download the newest layout stylesheet. This stylesheet is cosmetic and not required for Layout to work , but does provides useful samples and tips for styling a layout to achieve what you want. There are some changes in this regard from Layout 1.2.0...
New in RC30.79
New in RC30.78
New in RC30.77
New in RC30.76
New in RC30.75
New in RC30.74Restored the functionality to load-state into an already existing layout. This now works with the cascading-state functionality added in RC30.7. So by setting/restoring state in the outer-layout, it will also restore the state of all child-layouts, provided the state-data exists for them and providing the option is set for this. This demo has buttons at the bottom of the center-pane that will restore state to as it was when the page loaded, and can do so both with or without pane-animations... New in RC30.73
New in RC30.72
New in RC30.71
New in RC30.7Bug Fixes
Misc. Changes
New Layout-Container Functionality
Child-Layout ChangesA number of enhancements were added to expand integration between parent and child (nested) layouts. This includes name changes to most child options and methods...
parentLayout.refreshChildren( "center" );
This will cause layout to reprocess the 'children' options for the center-pane and try to create the layouts now. New State Management FeaturesLayout's state-management can now handle an unlimited number of layouts in a single sated-state object. This means a parent layout can save and restore the states of all its child/nested layouts, and all their children. So if you have a page-layout with 12 nested layouts inside it, the page-layout can handle state-management for them all! Any 'branch' of layouts can be handled as a unit, and be disconnected from the state of its parents.
Misc Internal Changes
New in RC30.62Bug Fixes
New in RC30.61Bug Fixes
New in RC30.6Bug Fixes
New Language OptionsLayout had multiple ways of changing the text used for tips and messages, which A) was somewhat confusing, and B) had some bugs. So the old $.layout.language functionality is now gone. All language settings are now part of the standard options. If you want to change the language settings globally, modify the global options. Language options are in 2 separate subkeys of the options: Developer Error Messages Error messages are 'layout options'. There is no reason to customize these for each layout, so if you want to customize them for a language, this is best done by modifying the global default options. Below are the defaults: $.layout.defaults = { ... , errors: { pane: "pane" // "layout pane element" - used only in error messages , selector: "selector" // "jQuery-selector" - used only in error messages , addButtonError: "Error Adding Button \n\nInvalid " , containerMissing: "UI Layout Initialization Error\n\nThe specified layout-container does not exist." , centerPaneMissing: "UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element." , noContainerHeight: "UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!" , callbackError: "UI Layout Callback Error\n\nThe EVENT callback is not a valid function." } ... End-User Tips & Messages The tooltips and alert for end-users are 'pane options', meaning they can be customized for each pane. By default all panes use the same tips – set in the 'panes' subkey. You can modify the global defaults, and the 'panes' default for each layout, and the settings for a specific pane if desired. Like all other options, the more specific settings will override the more general ones. $.layout.defaults = { ... , panes: { ... , tips: { Open: "Open" // eg: "Open Pane" , Close: "Close" , Resize: "Resize" , Slide: "Slide Open" , Pin: "Pin" , Unpin: "Un-Pin" , noRoomToOpen: "Not enough room to show this panel." // blank = no message , minSizeWarning: "Panel has reached its minimum size" // statusbar message , maxSizeWarning: "Panel has reached its maximum size" // ditto } } } NOTE that the tip-options that start with a capital letter (eg: Open, Close) should be specified with a capital letter (eg: Ouvrier, Fermier), unless you specifically want your tooltips to be displayed in all-lowercase. The new language options replace both the $.layout.language object and the old 'tip' options. All the options listed below no longer exist. However Layout's backwards-compatibility module will automatically rename your old options to their new equivalents, which are also shown below: OLD Options => NEW Options noRoomToOpenTip => tips.noRoomToOpen togglerTip_open => tips.Close togglerTip_closed => tips.Open resizerTip => tips.Resize sliderTip => tips.Slide NOTE that the togglerTip_closed is equivalent to tips.Open. This is because the new options are based on the 'word meaning', where the old options were based on the 'current pane state'. Here is a sample of how to customize the language in the layout options... // flat-format option format $("body").layout({ panes__tips__Open: "Ouvrier" // default for all panes in layout , panes__tips__Close: "Fermier" , west__tips__Open: "Ourvrier la Menu" // for west-pane only , west__tips__Close: "Fermier la Menu" }); –or– // sub-key option format $("body").layout({ panes: { // defaults for all panes in layout tips: { Open: "Ouvrier" , Close: "Fermier" } } , west: { // for west-pane only tips: { Open: "Ouvrier la Menu" , Close: "Fermier la Menu" } } }); –or– // flat-format and sub-key option formats combined $("body").layout({ panes__tips: { // defaults for all panes in layout Open: "Ouvrier" , Close: "Fermier" } , west__tips: { // for west-pane only Open: "Ourvrier la Menu" , Close: "Fermier la Menu" } });
New in RC30.5OVERVIEWThis release enhances Layout's event model. The goal is to provide the full range of event, method, and callback features available in jQuery and jQuery UI widgets. Layout now has many, many more ways for interacting with layouts This release also tweaks parent-child layout integration. Numerous layouts can now be specified as a single set of hierarchical options. Layout will automatically initialize each sub-layout in sequence, and link them all together for resizing and destruction (this can be overridden). The goal is to make a page full of nested layouts act as if they are one big layout, yet allow any part to be individually loaded, removed or manipulated. Fixed pane-resizing bug when using percentage or 'auto' size settingsThis fixed a bug that occurred under specific (rare) conditions that caused panes to not size to the correct size. The "No center-pane found" message now obeys showErrorMessage optionPreviously this error message would always appear when no center-pane was found, regardless how the showErrorMessage option was set. Now no message will appear if showErrorMessage=false, allowing for panes to be dynamically added without the user seeing an error. NOTE: Setting showErrorMessage=false will prevent Layout from telling you when something is wrong! So do not set this option while creating and testing your layout. Enable it only when you are ready to make your layout public. Refined linking of parent/child layoutsThe RC30 series closely integrates parent/child layouts. A few tweaks were added to this logic to avoid circular references between parents and childs. So here are the basics:
// get the child layout nested inside the outer-center-pane var childInstance = thisLayout.children.center; OR var childInstance = thisLayout.center.child; // get a layout nested 4 levels deep var deepChild = outerLayout.west.child.north.child.center.child.north; deepChild.close("west"); // close west-pane in nested layout // see if a layout is nested inside another layout if ( thisLayout.hasParentLayout ) { // find the parent-layout... // first get the 'container element' for this layout var $layoutContainer = thisLayout.container; // see if this layout is inside the 'pane' of a parent var parentLayout = $layoutContainer.data("parentLayout"); // if not directly-nested, must search up the DOM if ( !parentLayout ) { // find the closest layout-container wrapped around this one var $parentContainer = $layoutContainer.closest(".ui-layout-container"); if ( $parentContainer.length ) parentLayout = $parentContainer.data("layout"); } // trigger a resizeAll command on the parent-layout if (parentLayout) parentLayout.resizeAll(); } This demo has options for 7 layouts specified inside a single set of options... Child-Layout Create/Destroy Demo (nested_children.html) It illustrates how parent/child layouts autotomatically link together for creation and destruction. It includes sample for how to create child layouts inside any element, not just a 'pane', eg: // this layout is inside the 'content-div' of the center-pane , center__childOptions: { name: 'middle-center' // no extras options required – handled automatically } // this layout is inside a wrapper-div (NOT directly-nested) , east__childOptions: { name: 'middle-east' , containerSelector: '> div' // first child-div of pane } New event-binding options on layout-elementsPreviously layout event callbacks could only be set in the layout options, which also meant that each event could only have a single callback. This new binding option addresses both issues. // bind an onopen callback to the west pane-element $("body > .ui-layout-west").bind("layoutpaneonopen", function(){ alert("west.onopen callback #1"); }); // bind ANOTHER onopen callback to the west pane-element $("body > .ui-layout-west").bind("layoutpaneonopen", function(){ alert("west.onopen callback #2"); }); // bind an onresizeall callback to the layout container-element $("body").bind("layoutonresizeall", function(){ alert("layout.onresizeall callback"); }); When using element binding, all 'pane event names' are prefixed with "layoutpane", and all 'layout event names' are prefixed with "layout". Callbacks bound this way work exactly like callbacks set in the options, including being passed the same set of parameters. New method-triggering option on layout-container and layout-pane-elements.Previously layout methods always had to be called using the layout-instance object. Now methods can be activated using the standard jQuery event-triggering syntax. Method names use the same prefixes as the event-callbacks described above: Layout methods are prefixed with "layout" and pane methods are prefixed with "layoutpane". Following jQuery UI guidelines, methods names are all referenced in lower-case, even those that are normally in camel-case, eg: myLayout.resizeAll() => $pane.trigger("layoutresizeall") Trigger the resizeAll method directly on the layout container element $("body").trigger("layoutresizeall"); Open the west pane by triggering the command directly on the pane $("body > .ui-layout-west").trigger("layoutpaneopen"); Methods that contain the word "pane" have alternate versions without this redundancy, eg: // normal/full method name $("body > .ui-layout-west").trigger("layoutpaneremovepane"); // alternate/abbreviated method name $("body > .ui-layout-west").trigger("layoutpaneremove"); If you need to pass one or more parameters to a layout method, put them in an array, per standard jQuery rules for trigger()... // size pane to 200px $("body > .ui-layout-west").trigger("layoutpaneremove", [ 200 ]); // un-hide pane, and open it, with no animation $("body > .ui-layout-west").trigger("layoutpaneshow", [ true, true ]); Events triggered on layout elements DO NOT propagate/bubble-up, so triggering 'layoutpaneopen' on a pane in a nested-layout will not trigger an open event on the wrapping pane in the outer-layout. When calling layout methods, a 'pane element' can be passed instead of a 'pane name'.The new event model adds more flexibility in identifying panes to act on. You can now pass either the pane-name, the pane DOM-element, the pane as a jQuery object, or an 'event' triggered on the pane-element: // these 5 'closePane' commands all work the same // pane-name as a string myLayout.close("west"); // pane as a DOM element $(".ui-layout-pane").click(function(){ myLayout.close( this ); }); // pane as a jQuery object $("button#close-pane").click(function(){ myLayout.close( $(this).closest(".ui-layout-pane") ); }); // a 'click event' on a pane-element $(".ui-layout-pane").click( myLayout.close ); // trigger method discussed in previous feature $(".ui-layout-pane").trigger("layoutpaneclose"); Added new method to allow event callbacks to be manually triggeredA new layout.runCallbacks() method lets you trigger event callbacks for a specific event. This includes the callback set in the options plus any callbacks bound to the layout-element. This is different from 'trigger events' as discussed above, because the runCallbacks method only runs the callback for an event – it does NOT trigger the event to occur. So calling myLayout.runCallbacks("onopen", "west") is NOT the same as myLayout.open("west"). The purpose of the runCallbacks method is to allow callbacks to be fired without an event trigger, which means you could run "onopen" callbacks a second time, which would not happen if you simply called open("west") a second time — that would do nothing since the pane is already open. // trigger ALL west.onresize callbacks myLayout.runCallbacks("onresize", "west"); // trigger ONLY the west.onresize callback set in 'options' // ie, skip any callbacks set on the pane-element myLayout.runCallbacks("onresize", "west", true); This could be useful when manually manipulating content inside a pane, and then wanting Layout callbacks to reprocess the contents. New way to access layout-pane properties and methodsLayout RC30 added new 'pane' aliases to the layout-instance object. These aliases provide access to the properties of a pane, eg: var paneObject = myLayout.west; // paneObject now contains this data { name: "west" , pane: myLayout.panes.west // pane element , content: myLayout.content.west // content-div element , options: myLayout.options.west // pane options , state: myLayout.state.west // pane state , child: myLayout.children.west // pane child-layout Instance } // can also get paneObect from the pane-element var paneObject = $(".ui-layout-west").data("layoutPane"); The ability to get these pointers directly from the pane-element, without knowing the 'name' of the pane, makes writing generic functions much easier. For example: // function to close a pane if current size is less than 200px function closeSmallPane () { var layoutPane = $(this).data("layoutPane"); if (layoutPane.name === "center") return; // skip center panes if ( layoutPane.state.size < 200 ) layoutPane.pane.trigger("layoutpaneclose"); } // bind generic function to event on ALL panes on page $(".ui-layout-pane").mouseenter( closeSmallPane ); New in RC30.4Tweaked state-data so onclose_open callback gets more accurate info.This very minor update was added to coordinate with the pseudoClose 1.1 callback update. By returning more complete state-info about what the pane is doing, a pane's normal hide()/show() functionality can be used even when the pseudoClose callback is assigned. Fixed in RC30.3Fixed circular layout-pointer bugLayout RC30 added pointers both from parent to children layouts and from child to parent layout. However this creates an infinite circle of references from parent to child to parent to child... To resolve this, the [layout-instance].parent pointer has been removed. A new hasParentLayout flag has been added to layouts instead of a pointer to the parent layout: // this sample assumes all layouts have already been created... // GET the layout-instance of an inner-layout var innerLayout = $("#innerContainer").data("layout"); if ( innerLayout.hasParentLayout ) { // we can get an instance of the parent-layout from the // 'container' element of this child-layout var parentLayout = innerLayout.container.data("parentLayout"); // we could also check that layout for a parent... if ( parentLayout.hasParentLayout ) { var grandparentLayout = parentLayout.container.data("parentLayout"); } } Fixed bug in disable-text-selection-while-resizing featureDisabling text-selection relies on a jQuery UI utility, so this feature does not work without UI. Previously was generating an error in the console every time a Resizer-bar was hovered. Remove hack used to work around Webkit rendering issueThere are certain circumstances where Webkit (Chrome specfically) does not render the screen as fast as the Javascript runs. One example is opening a popup window that has a layout. Even though the layout is created after document.ready, the BODY elements is detected 'not visible'. This causes Layout to abort because it cannot initialize within a hidden container. The previous hack always added a delay for Chrome, but this meant Layout loaded asynchronously in Chrome. This can cause sequence-of-events issues in users' code. RC30.3 eliminates this and adds a delay only when the container is BODY (an outer-layout), and only if it does not load correctly the first time. This issue can be seen in (some versions of) Chrome on this test-page: test_popup_window.html. You may have to try the popup a few times - the rendering bug is erratic! New in RC30.2Size-to-grid optionA new option was added that will cause manual resizing of panes to 'snap to a grid' of the size specified. This option is passed to the Draggable widget, which handles the snap-to-grid functionality. This is a pane-option, so can be set as a default or customized per-pane. // Enable snap-to-grid , west__resizingGrid: 20 // pixels - default = false (none) Fix bug when sizing panes with a size-option of "100%" or -1The sizing logic was not correctly handling 100% size options, causing the pane to be auto-sized rather than sized to 100% of available space. This was fixed. New in RC30.1WARNING: Do not implement this version in a live website or application without testing it.I have tested this version thoroughly, but there are SO MANY changes that it is impossible to test every possible scenario. So for now this version should be treated as a "beta version". The RC29.15 version should be considered the "last stable version" until RC30 has been tested for a couple of weeks. The RC30 series makes significant changes to Layout's internal structure. Most of these changes are backwards compatible, but a few minor tweaks to your options may be required to get things exactly as you want because a few 'defaults' have been changed. GLOBAL Layout OptionsMany more things are now exposed globally, including the default layout options. Here is how to set 'global default options' that will apply to all your layouts: // IMPORTANT – always 'extend' the defaults - never 'replace' them! $.extend( $.layout.defaults, { showErrorMessages: false // NOTE the new 'panes' key - replaces 'defaults' , panes: { spacing_open: 10 , togglerLength: 60 , liveResizing: true } , north: { closable: false , spacing_open: 0 } }); OR by setting individual keys: // change a 'layout option' $.layout.defaults.showErrorMessages = false; // change a 'default pane option' $.layout.defaults.panes.liveResizing = true; NOTE that the key for 'default pane-options' was renamed from "defaults" to "panes". This makes the key's purpose more clear and avoids confusing the pane-defaults key with $.layout.defaults, which is the top-level of the options. Option Name ChangesA number of options have been renamed. Layout will still work with the old option names by automatically converting them to the new names on initialization, but it would be good for you to learn the new syntax. Here is a chart of all name recent changes: OLD Option Name: NEW Option Name applyDefaultStyles: applyDemoStyles resizeNestedLayout: resizeChildLayout resizeWhileDragging: livePaneResizing resizeContentWhileDragging: liveContentResizing triggerEventsWhileDragging: triggerEventsDuringLiveResize maskIframesOnResize: maskContents useStateCookie: stateManagement.enabled cookie.autoLoad: stateManagement.autoLoad cookie.autoSave: stateManagement.autoSave cookie.keys: stateManagement.stateKeys cookie.name: stateManagement.cookie.name cookie.domain: stateManagement.cookie.domain cookie.path: stateManagement.cookie.path cookie.expires: stateManagement.cookie.expires cookie.secure: stateManagement.cookie.secure You can access this list at a hash at: $.layout.backwardCompatibility.map New & Updated OptionsA number of new options were added, and the effect of some old options modified slightly.
Rather than list only the changes, here is a COMPLETE LIST of all Layout options in RC30,
with NEW options in red and RENAMED options in blue.
// set pointer to language-defaults key - used for default-tips on each pane
var lang = $.layout.language;
$.layout.defaults = {
/*
* LAYOUT & LAYOUT-CONTAINER OPTIONS
* - none of these options are applicable to individual panes
*/
name: "" // Not required, but useful for buttons and used for the state-cookie
, containerClass: "ui-layout-container" // layout-container element
, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark)
, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event
, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky
, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized
, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific
, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific
, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements
, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized
, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload
, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload
, autoBindCustomButtons: false // search for buttons with ui-layout-button class and auto-bind them
, initPanes: true // false = DO NOT initialize the panes onLoad - will init later
, showErrorMessages: true // enables fatal error messages to warn developers of common errors
, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code!
// Changing this zIndex value will cause other zIndex values to automatically change
, zIndex: null // the PANE zIndex - resizers and masks will be +1
// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships
, zIndexes: { // set _default_ z-index values here...
pane_normal: 0 // normal z-index for panes
, content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing
, resizer_normal: 2 // normal z-index for resizer-bars
, pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open'
, pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer
, resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged'
}
/*
* PANE DEFAULT SETTINGS
* - settings under the 'panes' key become the default settings for *all panes*
* - ANY pane-option here can also be set for a specific pane, which will override the 'panes' value
*/
, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings'
applyDemoStyles: false // renamed from "applyDefaultStyles" for clarity
, closable: true // pane can open & close
, resizable: true // when open, pane can be resized
, slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out
, initClosed: false // true = init pane as 'closed'
, initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing
// SELECTORS
//, paneSelector: "" // MUST be pane-specific - jQuery selector for pane
, findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector)
, contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane!
, contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content'
// GENERIC ROOT-CLASSES - for auto-generated classNames
, paneClass: "ui-layout-pane" // Layout Pane
, resizerClass: "ui-layout-resizer" // Resizer Bar
, togglerClass: "ui-layout-toggler" // Toggler Button
, buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin'
// ELEMENT SIZE & SPACING
//, size: 100 // initial size of pane - normally should be pane-specific -
, minSize: 0 // limit when manually resizing a pane (height for N/S panes, width for E/W)
, maxSize: 0 // ditto, 0 = no limit
, spacing_open: 6 // space between pane and adjacent panes - when pane is 'open'
, spacing_closed: 6 // ditto - when pane is 'closed'
, togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides
, togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden'
, togglerAlign_open: "center" // top/left, bottom/right, center, OR...
, togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right
, togglerTip_open: lang.Close // Toggler tool-tip (title)
, togglerTip_closed: lang.Open // ditto
, togglerContent_open: "" // text or HTML to put INSIDE the toggler
, togglerContent_closed: "" // ditto
// RESIZING OPTIONS
, resizerDblClickToggle: true // true = double-clicking anywhere on the resizer-bar will toggle the pane open/closed
, autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes
, autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed
, resizerDragOpacity: 1 // option for ui.draggable
//, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar
, maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES
, maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask
, maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes
, livePaneResizing: false // true = LIVE Resizing as resizer is dragged
, liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged
, liveResizingTolerance: 1 // how many px change before pane resizes, to control performance
// TIPS & MESSAGES - global defaults from $.layout.language (lang)
, noRoomToOpenTip: lang.noRoomToOpenTip
, resizerTip: lang.Resize // Resizer tool-tip (title)
, sliderTip: lang.Slide // resizer-bar triggers 'sliding' when pane is closed
, sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding'
, slideTrigger_open: "click" // click, dblclick, mouseenter
, slideTrigger_close: "mouseleave"// click, mouseleave
, slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open
, slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!)
, hideTogglerOnSlide: false // when pane is slid-open, should the toggler show?
, preventQuickSlideClose: $.layout.browser.webkit // handle problem when Chrome triggers slideClosed as it is opening
, preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over an open SELECT field in IE
// HOT-KEYS & MISC
, showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver
, enableCursorHotkey: true // enabled 'cursor' hotkeys
//, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character
, customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT'
// PANE ANIMATION
, fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size'
, fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration
, fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 }
, fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation
, animatePaneSizing: false // true = animate resizing when sizePane() is called - not applicable to drag-resizing
/* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set:
, fxName_open: "slide" // 'Open' pane animation
, fnName_close: "slide" // 'Close' pane animation
, fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true
, fxSpeed_open: null
, fxSpeed_close: null
, fxSpeed_size: null
, fxSettings_open: {}
, fxSettings_close: {}
, fxSettings_size: {}
*/
// CHILD/NESTED LAYOUTS
, childOptions: null // Layout-options for nested/child layout - even {} is valid as options
, initChildLayout: true // true = child layout will be created as soon as _this_ layout completes initialization
, destroyChildLayout: true // true = destroy child-layout if this layout is destroyed
, resizeChildLayout: true // true = trigger child-layout.resizeAll() when this pane is resized
// PANE CALLBACKS
, triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes
, triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true
, onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start
, onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end
, onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start
, onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end
, onopen_start: null // CALLBACK when pane STARTS to Open
, onopen_end: null // CALLBACK when pane ENDS being Opened
, onclose_start: null // CALLBACK when pane STARTS to Close
, onclose_end: null // CALLBACK when pane ENDS being Closed
, onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON***
, onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON***
, onsizecontent_start: null // CALLBACK when sizing of content-element STARTS
, onsizecontent_end: null // CALLBACK when sizing of content-element ENDS
, onswap_start: null // CALLBACK when pane STARTS to Swap
, onswap_end: null // CALLBACK when pane ENDS being Swapped
, ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized
, ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized
}
/*
* PANE-SPECIFIC SETTINGS
* - options listed below MUST be specified per-pane - they CANNOT be set under 'panes'
* - all options under the 'panes' key can also be set specifically for any pane
* - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane
*/
, north: {
paneSelector: ".ui-layout-north"
, size: "auto" // eg: "auto", "30%", .30, 200
, resizerCursor: "n-resize" // custom = url(myCursor.cur)
, customHotkey: "" // EITHER a charCode (43) OR a character ("o")
}
, south: {
paneSelector: ".ui-layout-south"
, size: "auto"
, resizerCursor: "s-resize"
, customHotkey: ""
}
, east: {
paneSelector: ".ui-layout-east"
, size: 200
, resizerCursor: "e-resize"
, customHotkey: ""
}
, west: {
paneSelector: ".ui-layout-west"
, size: 200
, resizerCursor: "w-resize"
, customHotkey: ""
}
, center: {
paneSelector: ".ui-layout-center"
, minWidth: 0
, minHeight: 0
}
};
NOTE that the options above do not include state-management, cookie or button options. These features are now layout plug-ins, so their options exist only if related plug-ins is loaded. For example, the layout.state plug-in will add a 'stateManagment' key to the defaults, which contains all the options specific to state-management, including cookie options. You can set all plug-in defaults globally within $layout.defaults, and specifically using your normal layout options. See the info on each plug-in below for a list of the options each will add. New Child Layout FeaturesLayout 1.3 has new options that make it more seamless to integrate multi-level layouts: // CHILD/NESTED LAYOUTS , childOptions: null // Layout-options for nested/child layout - even {} is valid as options , initChildLayout: true // true = child layout will be created as soon as _this_ layout completes initialization , destroyChildLayout: true // true = destroy child-layout if this layout is destroyed , resizeChildLayout: true // true = trigger child-layout.resizeAll() when this pane is resized All these options are new except resizeChildLayout, which was previously named "resizeNestedLayout". Below is a summary of the new functionality and versatility these options provide: Can now include the 'options' for ALL child-layouts within the options of the pane in the outer-layout that contains the innerLayout. In other words, all the options for both the outer-most layout and all child/nested layouts it contains can now be specified in a single options hash - if desired. Here's a sample showing the options for a page layout that contains child-layouts: // page layout options PLUS options for 5 nested layout - 2-levels deep $("body").layout({ // page layout - outer-most layout name: "page" panes: { // page layout -> pane-defaults spacing_open: 0 } , center: { // page layout -> center-pane minWidth: 400 , minHeight: 300 // 2nd level layout inside this center-pane , childOptions: { name: "page_center" , resizable: false , center: { // page_center layout -> center-pane // 3rd level layout inside this center-pane childOptions: { name: "page_center_center" , west: { // layout -> center-pane closable: false } } } , west: { // page_center layout -> west-pane // 3rd level layout inside this west-pane childOptions: { name: "page_center_west" , panes: { // page_center_west layout -> pane-defaults closable: false } } } } } , east: { // page layout -> east-pane // 2nd level layout inside this east-pane childOptions: { name: "page_east" , panes: { // page_east layout -> pane-defaults closable: false } , center: { // 3rd level layout inside this center-pane childOptions: { name: "page_east_center" , panes: { // page_east_center layout -> pane-defaults spacing_open: 0 } } } } } }); Child Layouts can also be created by assigning various option hashes: // layout options common to both east & west sidebars var sidebarLayoutOptions = { resizable: false , closable: false , spacing_open: 0 }; // layout options for 3rd level layout (page -> center -> center) var pageCenterCenterLayoutOptions = { spacing_open: 0 }; // layout options for 2nd level layout (page -> center) var pageCenterLayoutOptions = { spacing_open: 0 , center__childOptions: pageCenterCenterLayoutOptions }; // page layout options PLUS options for 5 nested layout - 2-levels deep $("body").layout({ // page layout - outer-most layout name: "page" panes: { // page layout -> pane-defaults spacing_open: 0 } , center: { // page layout -> east-pane minWidth: 400 , minHeight: 300 // 2nd AND 3rd level layouts inside this center-pane childOptions: pageCenterLayoutOptions } , west: { // page layout -> center-pane minSize: 150 // 2nd level layout inside this west-pane , childOptions: sidebarLayoutOptions } , east: { // page layout -> center-pane minSize: 150 // 2nd level layout inside this east-pane , childOptions: sidebarLayoutOptions } }); How Child Layouts WorkLayout has always had child layouts, and the functionality of this does not change. The only change is tighter and easier integration between parent & child layouts. If you use the methods above to assign child layouts, an 'Instance pointer' is automatically created in the parent layout to the child layout. For example, if there is a child-layout inside the center-pane of the outer-layout, you can access the child layout like so: // create the outer-layout with a child-layout inside the center-pane var outerLayout = $("body").layout({ name: "page" , center: { // 2nd level layout inside this center-pane , childOptions: { name: "page_center" , resizable: false } } }); METHOD #1 access the child-layout through the 'children' hash in the outer-layout var innerLayout = outerLayout.children.center; innerLayout.resizeAll(); METHOD #2 access the child-layout through the 'center' hash in the outer-layout var innerLayout = outerLayout.center.child; innerLayout.resizeAll(); Even if you do not use the child-options feature and create child layouts individually, Layout will still create an instance-pointer to the child layout - if the child-layout has the outer-pane as its 'container' element. You can also specifically assign one layout as the child of another, like so: // create the outer-layout var outerLayout = $("body").layout(); // create a layout inside a descendant element - and set it as a 'child' of outLayout->center outerLayout.children.center = $("#wrapper").layout(); -or- outerLayout.center.child = $("#wrapper").layout(); Initialization of child layouts is automatic - unless you set the option initChildLayout=false (this can be set for each pane). Destruction of child layouts is also automatic, unless you set the option destroyChildLayout=false. This means that an entire page of layouts can be created or destroyed with a single command, as long as the child-layouts are associated with their parent pane. // Child-Access Method #1 // access the child-layout through the 'children' hash in the outer-layout var innerLayout = outerLayout.children.center; innerLayout.resizeAll(); // Child-Access Method #2 // access the child-layout through the 'center' alias in the outer-layout var innerLayout = outerLayout.center.child; innerLayout.resizeAll(); // Access layouts multiple-levels deep var pageLayout = $("body").layout(); // get layout-instance // find a layout nested 3-levels deep inside the page-layout var deepLayout = pageLayout.center.child.west.child.north.child; deepLayout.resizeAll(); New Layout 'parent' keyAlong with the new 'children' key, layouts also have a new 'parent' key. If the layout can determine that it is a child of another layout, a pointer to the parent-layout is set in the [Instance].parent key. For example: // assuming all layouts have already been initialized... var innerLayout = $("#innerContainer).layout(); // get inner-layout 'instance' var parentLayout = innerLayout.parent; // get parent-layout 'instance' It is rare that you should ever need to access a parent-layout, but this key is provided as a compliment to the 'children' key. Note that this doesn't tell you which 'pane' of the parent-layout the innerLayout is inside. New Pane-Alias Keys in Layout InstanceAs indicated above, the layout instance-object now includes a key for each pane in the layout. These keys provide an alternate method for acessing pane-specific data: 'children', 'options' & 'state': // get the layout instance var myLayout = $("body").layout(); // standard method for accessing pane-specific data var options = myLayout.options.west; var state = myLayout.state.west; var children = myLayout.children.west; // alternate method for accessing pane-specific data var options = myLayout.west.options; var state = myLayout.west.state; var children = myLayout.west.children; // or using more compact syntax var west = myLayout.west; var options = west.options; var state = west.state; var children = west.children; These new aliases can be useful for writing clearer code, especially in generic functions. New Pane Masking OptionsLayout has long had a masking option intended to mask iframes so that it's possible to drag the resizers over top of them. However the masking DIV used does not work for 'objects', like video players, Google maps, applets, etc. So this version add an updated masking system that can also mask these objects. , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes The old "maskIframesOnResize" option is now "maskContents". Enabling this option is sufficient to handle iframes and anything else other the applets/objects. If you have an object that needs masking, also enable the maskObjects option. The object mask works by covering the pane with a transparent iframe. In some browsers this makes the object 'disappear', and in others it doesn't. But the objects is effectively masked for Layout's needs regardless whether it is still visible or not. When the object mask is used, the content mask (a transparent DIV) is also used, because the transparent iframe must also be masked! The only time the maskZindex option needs to be changed is if you have elements inside the pane that have a high zIndex applied. In this case, the maskZindex should be set so it is 'higher' than any other element inside the pane it is masking. New Plug-in ArchitectureLayout now has a flexible plug-in system. Plug-ins can be integrated with important layout events, and can extend the default options (not all plug-ins have options). Using this new capability, all 'extra features' have been removed from the Layout core and moved into plug-ins. These plug-ins include:
For now, ALL plug-ins are bundles in the same JS file as the core Layout plug-in. This provides full backwards compatibility and simplifies downloading. Eventually I'll add a 'builder' to the website so you can choose which plug-ins (and callbacks) you want, and only those will be bundled into the download file – similar to how jQuery UI downloads work. (Custom callbacks are NOT currently included inside the core Layout file.) New Layout Plugin ArchitectureLayout now has a plugins systems. Layout options and other data is now easy to extend, and a number of event-arrays have been provides so plugins can hook into events easily. When a plugin is loaded, it extends Layout's functionality. The plugin is automatically available to _all_ layouts on the page, though many plugins have options to enable or disable their features. Plugins JS files be loaded AFTER the layout file is loaded. However in RC301.1, I have included all plugins inside the main Layout file , so there is not need to load extra files. You can test whether a plugin is loaded by checking the $.layout.plugins hash. Each plugin will add a key here to indicate that it has loaded. So you can do check like this: if ( $.layout.plugins.stateManagement ) { doSomething(); } State Management PluginThis plug-in has the same functionality as state-management in previous version, however the options have been reorganized so that all related options now fall under the key added by the plugin: $.layout.defaults.stateManagement = { enabled: false // true = enable state-management, even if not using cookies , autoSave: true // Save a state-cookie when page exits? , autoLoad: true // Load the state-cookie when Layout inits? // List state-data to save - must be pane-specific , stateKeys: "north.size,south.size,east.size,west.size,"+ "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ "north.isHidden,south.isHidden,east.isHidden,west.isHidden" , cookie: { name: "" // If not specified, will use Layout.name if set, else just "Layout" , domain: "" // blank = current domain , path: "" // blank = current page, '/' = entire website , expires: "" // blank = session, Date = expiry date, n>0 = days, null/0/n<0 = delete , secure: false // true = use cookie only for HTTPS pages - always encrypted } };
Button Binding Pluginfoo bar Change in how '-hover' Classes AddedThe extra "hover classes* are now always added to resizers and togglers - regardless whether the resizable or closable options are enabled. Previously the hover-classes were added only if resizable/closable were enabled, but that is not ideal since the purpose of the hover-classes is simply to standardize CSS for old browsers like IE6, which do not understand the :hover pseudo-class on anything other than hyperlinks. If you want to control the hover styles for elements, this should be done purely with CSS. So the -hover layout-classes are now consistent with the :hover pseudo-class, regardless of JavaScript functionality. So IF you want to accommodate IE6, use "-hover" on classNames, like this: .ui-layout-resizer-hover { background: #FCC; } .ui-layout-resizer-west-hover { background: #FCC; } ...INSTEAD OF using the CSS ":hover" pseudo-class... .ui-layout-resizer:hover { background: #FCC; } .ui-layout-resizer-west:hover { background: #FCC; }
New in RC29.15New Initialization FunctionalityPreviously you could not initialize a layout when the container-element was 'hidden'. So when using layouts inside tabs or any other time the layout was not initially visible, custom logic was required so the layout was created only after it became visible. Now ALL layouts can be initialized on-page-load – whether visbible or hidden. If the layout is hidden — or if the center-pane element does not exist — then the layout will "partially initialize". The loads the options and creates the layout instance, but does not initialize the layout-panes. Each time a layout method is called — like resizeAll() — the layout will check its status and complete initialization if it can. The same goes for automatic events triggered by window.resize or outer-layouts. If the layout still can't complete initialization, it will ignore the command given and continue waiting. Or, to specifically tell the layout to complete initialization, call: myLayout.initPanes(). If possible, initialization will complete; If not, the command is ignored, as it is if initialization has already completed. Calling any method will do the same thing, so resizeAll() is just as good as initPanes(). The most common situation where partial initialization is useful is a layout-inside-a-tab – inner-layouts are often hidden inside an inactive tab. Instead of a special function, all you need now is a simple callback on tabs.show... $(document).ready(function(){ // create the tabs pageLayout.panes.center.tabs({ show: function(){ tabLayout.resizeAll(); } }); // create the page layout pageLayout = $("body").layout( pageLayoutOptions ); // create inner-layout (currently hidden) tabLayout = $("#tab2").layout( tabLayoutOptions ); } OR if the inner layout is created first... $(document).ready(function(){ // create the page layout pageLayout = $("body").layout( pageLayoutOptions ); // create inner-layout (currently hidden) tabLayout = $("#tab2").layout( tabLayoutOptions ); // create the tabs pageLayout.panes.center.tabs({ show: tabLayout.resizeAll }); // adjust page-layout after creating the tabs pageLayout.resizeAll(); } This code also works for Ajax-tabs where the pane-elements do not even exist yet! The layout will wait until it can find the 'center-pane' element before completing initialization. Two of the Tabs demos have been updated to use the new features and syntax:
New Layout Options
New Layout Methods
Other Updates
New Add-ons — "Callbacks"I now package custom code snippets into reusable callback functions that can be loaded into the $.layout namespace. This makes code for special situations easy to reuse. I have created 2 callbacks so far, including one that leverages the new integration functionality. All callbacks can be downloaded in a single file, or as individual files: Callbacks Library — contains all callbacks in one file: resizeTabLayout Callback — automatically finds a layout nested inside a tab and initializes or resized it: resizeTabLayout Example $(document).ready(function(){ // mouseleave event - 300 is the minimum $("#myTabs").tabs({ show: $.layout.callbacks.resizeTabLayout }); // OR mixed with custom code $("#myTabs").tabs({ show: function (evt, ui) { $.layout.callbacks.resizeTabLayout() [ other code ] } }); // OR without the callback method $("#myTabs").tabs({ show: function (evt, ui) { var tabLayout = $(ui.panel).data("layout"); if ( tabLayout ) tabLayout.resizeAll(); [ other code ] } }); }); pseudoClose Callback — prevents iframes, flash and other objects from reloading when the pane closes. pseudoClose Example $(document).ready(function(){ // mouseenter event - 0 = instant open south__onclose_start: $.layout.callbacks.pseudoClose // or $("#myTabs").tabs({ show: function () { $.layout.callbacks.pseudoClose() [ other code ] return false; // CANCEL normal close } }); New in RC29.14New OptionsNew options for setting a 'delay' when triggering slide-open (mouseEnter) and slide-closed (mouseLeave). Options have no effect when slide-trigger is click or dblClick. slideTrigger_open: "mouseenter" , slideTrigger_close: "mouseleave" // default , slideDelay_open: 300 // mouseenter event - 0 = instant open , slideDelay_close: 300 // mouseleave event - 300 is the minimum New in RC29.13New & Removed Classnames
New & Renamed EventsThe onload and onunload events have been extended with _start & _end versions. The new onload_end event is useful for modifying the layout after it is created.
New Layout Methods
Bug Fixes
Added in RC29.12
Added in RC29.11
Fixed in RC29.10
Added in RC29.9
Fixed in RC-29.8
Fixed in RC-29.7
Fixed in RC-29.6
Fixed in RC-29.5
Fixed in RC-29.4
Fixed in RC-29.3
Fixed in RC-29.2
Fixed in RC-29.1
Added in RC-29NOTE: This is only some of the refinements planned for RC-29. It was taking too long to get them all completed and tested, so I broke the updates into 2 releases: RC-29 is the first half - RC-30 will add the remainder. RC-30 will include some fundamental changes to some option-names and utility methods in preparation for finalizing version 1.3.0. Fixed numerous small bugs, like no longer adding 'hover' classes to disabled resizers, making sure required resizing is always triggered, etc. Updated header/content sizing (ie, .ui-layout-content). Now faster and more accurate. Added callbacks for content-sizing:
Fixed the "text selection while resizing" issue, even in Google Chrome. The "noSelectionWhileDragging" option no longer exists because now text-selection is always disabled when resizing because the new method has no negative effects. Added callbacks for manual resizing:
Fixed pane-swapping functionality, and... Added callback for pane-swapping:
Added action methods for 'sliding'.. (Previously required passing extra params to the open() and close() methods):
Added option to prevent Chrome from immediately closing a pane after it has 'slid open'. This is automatically enabled for Webkit browsers, but not for others. You can override the default if necessary:
The old option for handling this issue has been removed:
Added automatic nested-layout resizing. This change affects the options you set. When you have a 'directly nested' layout (definition below), you no longer need to set a callback to resize the nested layout. If you use RC-29 and still have old onresize callbacks set, the nested-layout will be resized twice. This doesn't hurt anything, but is an unnecessary drag on performance, so old callbacks should be removed. This functionality is controlled by a new option and enabled by default for all panes:
There is little need to ever disable it, but it could be if necessary, eg:
What is a "Directly Nested Layout"? A "directly-nested-layout" is one where the same element that is a 'pane' in an outer-layout is also the 'container' for an inner/nested layout. In this case, Layout will recognize the nested layout when the outer-pane resizes, and so automatically trigger resizeAll() on the nested-layout after it finishes resizing the outer-pane. Example: Directly-Nested Inner-Layout -- WILL Auto-Resize <div class="ui-layout-center"> <!-- outer pane / inner container --> <div class="ui-layout-north"> North </div> <div class="ui-layout-center"> Center </div> <div class="ui-layout-couth"> South </div> </div> HOWEVER, if the inner-layout in inside any kind of 'extra wrapper-div' as a container - ie, not the outer 'pane' itself - then it is not 'directly nested'. In this case Layout will not know it exists, so an onresize callback will still be needed on the outer-pane, as it is now. Example: Inner-Layout with 'Extra Wrapper' -- Will NOT Auto-Resize <div class="ui-layout-center"> <!-- outer pane --> <div id="innerLayoutWrapper"> <!-- wrapper / inner container --> <div class="ui-layout-north"> North </div> <div class="ui-layout-center"> Center </div> <div class="ui-layout-couth"> South </div> </div> </div> There are A LOT of changes in this release, so please report any errors you find to help debug it. There will be more big changes coming in RC-30, which will become Layout 1.3.0 Final after it is tested for a few weeks. Added in RC-28
Added in RC-27
Added in RC-26
Added in RC-25
Added in RC-24
Added in RC-23
Fixed in RC-22
Fixed in RC-21
Fixed in RC-20
Fixed in RC-19
Added in RC-18New option: resizeWithWindowMaxDelay This option works in concert with resizeWithWindowDelay to control layout resizing during browser-window resizing. The 'MaxDelay', if set, will cause the layout to resize every XX milliseconds even if the window is still being resized. For example... $("body").layout({ resizeWithWindowDelay: 300 , resizeWithWindowMaxDelay: 1000 }); If no window-resize event is triggered for 300ms, the layout will be resized. This timer is reset each time a window-resize event is detected. So as long as the user keeps resizing the window, it will keep resetting the 300ms timer - waiting for the user to finish. However, even if the user keeps resizing the window, the layout will resize every 1000ms anyway because of the resizeWithWindowMaxDelay option. If you do not want your layout to resize until the user is 'done' resizing the window, then leave resizeWithWindowMaxDelay as 0 (default), which disables this extra functionality. Fixed in RC-17
[pane].trackMouseWhenSliding: false // default Fixed in RC-16
Added in RC-15
zIndex: null // default - same as: 1
resizerDblClickToggle: true // default
noSelectionWhileDragging: true // default
triggerEventsWhileDragging: true // defaultwest__triggerEventsWhileDragging: false // sample
Instance.resizersExample: var westResizerBar = myLayout.resizers.westInstance.togglersExample: var westToggleBtn = myLayout.togglers.west
Fixed in RC-5 to RC-14These releases were mostly bug fixes. Some new features were probably added, but I do not have a list available right now. Updated in RC-4.2
Added in RC-4.1
Added in RC-4Here is the 1.3.RC4 version (I skipped RC3). I fixed all known bugs and completed all the remaining features I was working on. Layout will now autoClose (if pane is 'closable') or autoHide panes when there is not enough room for them to fit. This is determined based on the border-pane's minSize and center minWidth/minHeight. If you want the pane will re-open when there is enough room again, enable the autoReopen option. autoReopen: false // default NOTE that autoOpen does not work well with live-resizing because the pane will re-open as soon as there is even 1px of space available, making the pane very small. There is an new option for the 'auto' and percentage-sizing capabilities. If you enable this, layout will recalculate percentages every time the layout is resized to try and maintain the same ratios... autoResize: false // default If you enable this for a pane that has 'auto' size, the pane will resize to fit wrapped content. If a pane is 'manually resized', autoResize is automatically turned off for that pane. If minSize rules prevent layout from achieving the percentage-size specified, the panes will be smaller. However, Layout will continue trying to achieve the full size every time the layout resizes. The option previously named "setWindowResizeTrigger" has been renamed to "resizeWithWindow". Normally you do not have to worry about this, but it can be useful with a nested layout that is inside a 'non-layout container'. resizeWithWindow: true // default, UNLESS container is a 'pane' of an outer-layout A new companion options sets a 'delay' before resizing the layout when the window is resizing. The default is 250ms, which makes window resizing smoother because the layout is not trying to resize 50-times/second resizeWithWindowDelay: 250 // default Layout has 2 new methods: swapPanes() and destroy() myLayout.destroy() ...will REMOVE the layout, putting everything back as it was originally. You can see a demo here: /demos/destroy.html myLayout.swapPanes("west", "east")...will MOVE a pane(s) from one edge to another. You can move any pane to any side. If only one side has a pane, then the pane is 'moved'. If both the source and target sides have panes, then the 2 panes 'swap sides'. Layout will try to intelligently resize the panes as needed. You can see a demo here: /demos/swap_panes.html Here are some additional pages I used to test RC4 features...
|
||||
![]() |
|||||