|
Subscribe to jQuery UI Layout |
Email: |
These instructions are for the current release version, 1.2.0. For assistance with beta or release candidate versions, or for questions or problems not addressed by this documentation or the tips page, visit the UI Layout discussion group:
UI Layout creates a 'page-layout' with an auto-sizing 'center pane' surrounded by up to four collapsible and resizable 'border panes' (north, south, east & west). It can also create multiple headers & footers inside each pane.
For more complex layouts, you can nest layouts within layouts. Or use an iframe as a pane to create a 'sub-form' that can have its own layout. The possibilities are unlimited - from simple fixed headers or sidebars to rich applications.
Layouts are created from existing elements (divs, iframes, etc), so will degrade gracefully. You can even make some regions invisible, so they will not show if the user does not have Javascript enabled.
Open All Sections Close All Sections
Required
Optional
We're unaware of any browsers that do not work, but only these have been tested:
After viewing a demo, click 'Back' to return to this page
SEE MORE demos & samples on our demos page.
This is a minimalist layout with all 4 border-panes, with basic styling added for demo purposes (applyDefaultStyles = true):
<html> <head> <script src="jquery.js"></script> <script src="jquery.layout.js"></script> <script> $(document).ready(function () { $('body').layout({ applyDefaultStyles: true }); }); </script> </head> <body> <div class="ui-layout-center">Center</div> <div class="ui-layout-north">North</div> <div class="ui-layout-south">South</div> <div class="ui-layout-east">East</div> <div class="ui-layout-west">West</div> </body> </html>
VIEW this example page: example.html
To help you understand layout options and instructions, here is the terminology used...
The layout container is the element specifed when creating a layout. Most commonly this will be the 'body' element, but you could put a layout inside any block-element, including inside a 'pane' of another layout (a nested layout).
Here is an example that creates a layout covering the entire page ('body'), and a second layout that is inside the 'center pane' of the first layout:
$("body").layout(); $("body > .ui-layout-center").layout();You can see a sample of this layout in the complex.html demo page.
When a border-layout is created, it has up to five regions: 'north', 'south', 'west', 'east' and 'center'. (Only a center region is required) These regions/elements are referred to as 'panes' - as in window-panes. Most options apply only to the 'border-panes', meaning all except the center-pane.
NOTE: All panes are existing DIVs (or other elements) in your HTML mark-up — panes are NOT auto-generated. The pane elements must be direct 'children' of the container element - i.e., not nested inside other elements. There is an exception for nesting inside a FORM, or if you use an ID as a selector instead of the default class-selectors.
TIP: Using an IFRAME as a pane works great! Since the iframe auto-sizes, you will never again have TWO vertical scrollbars on your page. This website's Discussion and Issues pages use a layout with an iframe to incorporate pages from other websites.
In this document, when 'PANE' is written in uppercase, it means one of the panes. For example:"ui-layout-PANE"means"ui-layout-north", or"ui-layout-center", etc.
The auto-generated resizer-bar and toggler-button elements (DIVs) are 'attached' to their correpsonding border-pane and have related classNames, for example:"ui-layout-resizer-west"is the resizer-bar for the west-pane:"ui-layout-pane-west".
'Pane spacing' refers to the space on the 'inside edge' of a border-pane. For the north pane, this is the bottom edge, for the west pane, it's the right edge. A pane can have -0- spacing, which means no space between it and the adjacent panes. If a pane has no spacing, then it cannot have a resizer-bar or toggler-button.
Spacing can be different when the pane is open than when closed: Each pane has options forspacing_openandspacing_closed
A DIV element is created that fills the 'spacing' between panes. The resizer DIV is always the full width of the spacing and the full height of the pane. Panes can have different spacing set for open and closed states - the resizer-bar is automatically resized and repositioned each time a pane is opened or closed.
Actually there is not a separate 'slider-bar' element - the resizer-bar acts as a slider-bar when the pane is 'closed'. Clicking or hovering the resizer/slider bar will 'slide a pane open', meaning it slides over top of the adjacent panes without resizing them. When the mouse moves off the pane, it automatically slides closed again. This feature can be customized or disabled for each pane in the layout options.
A DIV element is created inside the resizer DIV. This DIV acts as a 'toggler-button' to open and close a pane. You can make this look like anything you want by adding color, borders, and/or a background-image to it. Or you can insert text, images or custom HTML inside the toggler using the togglerContent options.
The toggler button always fills the full width of the resizer-bar (inside resizer borders). Toggler length is an option, which can be either a pixel-value, like 50, or it can be "100%" (or -1). If set to 100%, the toggler completely covers the resizer-bar (except for resizer borders). Note that this prevents 'resizing' when the pane is open, and 'sliding open' when the pane is closed.
Each pane can have different Toggler lengths, and these can be different depending on whether the pane is open or closed, for example:
, togglerLength_open: 50 , togglerLength_closed: "100%" , north__togglerLength_open: "100%" , south__togglerLength_open: "100%"
A layout is creating by calling the method on the 'container element' of the layout, and passing layout options (optional):
$('body').layout( [options] );
If the layout-instance is assigned to an object pointer (recommended)...
var myLayout = $('body').layout();
...then a number of properties, methods and utilities can be accessed to control or inspect that 'specific layout instance':
// init instance var var myLayout = $('body').layout(); // read layout 'options' var is_west_resizable = myLayout.options.west.resizable; var north_maxHeight = myLayout.options.north.maxSize; // get layout 'state' var is_west_open = myLayout.state.west.isOpen; var north_size = myLayout.state.north.size; // layout methods myLayout.toggle("north"); myLayout.sizePane("west", 300); // layout utilities myLayout.addPinBtn("#myPinButton", "west"); myLayout.allowOverflow("north");
An array of 'pane objects' (panes.north, panes.south, etc). Each pane-element is in a jQuery wrapper. If a pane does not exist in the layout - for example no south-pane - thenpanes.south == false- instead of being a jQuery element.
A hash containing all the options used to generate the layout, including both default and user-specified options. Options are returned in 'Sub-Key format' - see Options below.
A hash containing the dimensions of all the elements, including the layout container. Dimensions include borders and padding for:top, bottom, left, right, plusouterWidth, outerHeight, innerWidth, innerHeight.var containerWidth = myLayout.state.container.innerWidth; var isWestOpen = !myLayout.state.west.isClosed;SEE Reading the Layout-State for more information.
Most methods require a 'pane' to be specified - usually a 'border-pane':"north","south","east"or"west".
Toggle the specified pane open or closed - the opposite of its current state.
Open the specified pane. If the pane is already open, nothing happens. If the pane is currently 'hidden' (not just 'closed'), then the pane will be unhidden and opened.
Close the specified pane. If the pane is already closed, nothing happens.
Hide the specified pane. When a pane is hidden, it has no spacing or resizer-bar or toggler-button - it is completely invisible, as if it did not exist.
Un-hide the specified pane. Normally also opens the pane, but if you pass 'false' as the second parameter, then pane will un-hide, but be 'closed' (slider-bar and toggler now visible).
This sizes the pane in the direction it opens and closes - for north and south panes, size=outerHeight, for east and west panes, size=outerWidth. The pane will only resize within its minSize and maxSize limits.
Resizes the 'content container' inside the specified pane. Content is resized automatically when the pane is resized or opened, so this method only needs to be called manually if something 'changes the height' of a header or footer element in the pane.SEE Content Scrolling (Headers & Footers) for more information.
Resizes the entire layout to fit its container. This method runs automatically for all layouts when the browser window is resized.When a layout is inside another element (its 'container'), and that container-element can be 'sized' without resizing the entire window, then layout.resizeAll() should be called so the inner-layout will resize when its container resizes.
In the example below, a 'resize callback' is added to the outerLayout.center pane because it is the container for the innerLayout:
outerLayout = $("body").layout({ center__onresize: "innerLayout.resizeAll" }); innerLayout = $("div.ui-layout-center").layout();
SEE Tips, Tricks and Utilities for details on these special utility methods.
Layout options are passed when creating a layout. There are options to customize almost every aspect of a layout, but all options are optional. You can use the default options to create a fast and simple layout, or create a completely custom look for your application. Callback options can also help integrate a layout with your design.
You can either pass the options inline:
$("body").layout({ option1: value, option2: value });
OR it may be convenient to save them in a var and pass that:
var myOptions = { option1: value, option2: value }; $("body").layout( myOptions );
There are 2 different formats you can use to specify options:
With this format, every option must be inside either the 'defaults' sub-key or a sub-key for a specific 'pane'...
These are the options for the 'Inner Layout' on the complex demo page
$("body").layout({ defaults: { fxName: "slide" , fxSpeed: "slow" , spacing_closed: 14 , initClosed: true } , north: { fxName: "none" , spacing_closed: 8 , togglerLength_closed: "100%" } , south: { fxName: "none" , spacing_closed: 8 , togglerLength_closed: "100%" } });
List format uses prefixes to identify pane-specific options instead of separate sub-keys. The prefix is the pane's name and TWO underscores, eg:"north__fxName". Options specified without a prefix (eg, fxName) are considered 'defaults'. You can also prefix default options -"defaults__fxName"- but the prefix is not necessary.
These are the same options shown above, but in list format. List format allows options to be specified in any order, so related default & pane-specific options are grouped together here:
$("body").layout({ fxName: "slide" , fxSpeed: "slow" , north__fxName: "none" , south__fxName: "none" , spacing_closed: 14 , north__spacing_closed: 8 , south__spacing_closed: 8 , north__togglerLength_closed: "100%" , south__togglerLength_closed: "100%" , initClosed: true }
Options specified for an individual 'pane' always override options specified as 'defaults'.
If the north, south and east panes should be 'closed' when the layout is created - so only the west pane is open - then just 2 options are needed:
initClosed: true west__initClosed: false
This causes all panes except west to be closed when created.
Options with 'selector' in their name - like 'contentSelector' - require a COMPLETE jQuery selector string. So if the selector is a className, start it with a period (.) - if the selector is an ID, start it with a pound sign (#). Any valid jQuery selector string can be used.
Options with 'class' in their name - like 'togglerClass' - do NOT start with a period. The classNames specified are applied to the element, plus are used as a root for additional classNames. For example, if you set this options
togglerClass: "myToggler"
This would generate ALL these classes for the toggler-button on the west-pane:
class="myToggler myToggler-west myToggler-open myToggler-west-open"
When the west pane is closed, the last two classes would change to:
class="... myToggler-closed myToggler-west-closed"
This provides total control of elements using CSS - you can apply global styles using "myToggler" or "myToggler-closed", and styles for specific elements using "myToggler-west" or "myToggler-west-open".
NOTE: Use the default classes if you want to use a standard 'Layout theme'. If you are using custom layout styles, then you can change the default class-names using the options.
Options can be set as 'defaults', which apply to ALL border-panes - or be set for specific panes (eg, "north"). There are a few options cannot be set as defaults, including 'paneSelector', 'resizerCursor' and the pane-callback options.
Options are listed indicating their default values. Where applicable, a list and/or description of other possible values is shown in brackets.
When this is enabled, the layout will apply basic styles directly to resizers & buttons. This is intended for quick mock-ups, so that you can 'see' your layout immediately.Normally this should be set as a default option, but it can be set 'per-pane':
// enable for ALL panes (List-style options) $("body").layout({ applyDefaultStyles: true }); // enable for all except the west-pane $("body").layout({ applyDefaultStyles: true , west__applyDefaultStyles: false });If this option is enabled, use"!important"to override the default styles.
// 'important' required ONLY when applyDefaultStyles=true .ui-layout-pane { background-color: #EEE !important; } .ui-layout-resizer { background-color: #666 !important; }TIP: Disable or remove this option once you create your own layout styles or specify a layout-theme stylesheet. For sample layout CSS, view the code in the simple.html demo – that CSS replicates the styles applied by this option.
This option handles of bookmarks that are passed on the URL of the page:http://www.site.com/page.html #myBookmarkThe default functionality of bookmarks is broken when using a layout because the position and scrolling of pane elements are altered after the page loads. Enabling this option (enabled by default) causes the bookmark to be re-applied after the layout is created, causing the 'pane' containing the bookmark/anchor to be scrolled to bring it into view.
This option should be left enabled in most cases, but if content in the layout-panes is never bookmarked, then you could disabled it.
NOTE: This is a global option, so set in the top level of the options:
// Sub-Key or List style options $("body").layout({ scrollToBookmarkOnLoad: false });
If 'true', then when moused-over, the pane's zIndex is raised and overflow is set to 'visible'. This allows pop-ups and drop-downs to overlap adjacent panes.WARNING: Enable this only for panes that do not scroll!
SEE Working with Drop-Downs and Pop-Ups for more information.
Can a pane be closed?
When open, can a pane be resized?
When closed, can a pane 'slide open' over adjacent panes?
Default values are: ".ui-layout-north", ".ui-layout-west", etc.
Any valid jQuery selector string can be used - classNames, IDs, etc.To allow for 'nesting' of layouts, there are rules for how pane-elements are related to the layout-container. More flexibility was added in version 1.1.2 to handle panes are nested inside a 'form' or other element.
Rules for the relationship between a pane and its container:
- When an 'ID' is specified for paneSelector, the pane-element only needs to be a descendant of the container – it does NOT have to be a 'child'.
- When a 'class-name' is specified for paneSelector, the pane-element must be EITHER:
- a child of the container, or...
- a child of a form-element that is a child of the container
(must be the 'first form' inside the container)Example: Panes are 'children of the container' (normal):
$(document).ready(function() { // all panes are 'children' of body (normal) $("body").layout(); }); </head> <body> <div class="ui-layout-north"> <div class="ui-layout-center"> <div class="ui-layout-west"> </body>Example: Panes are 'children of the first child-form':
$(document).ready(function() { // 'body' is the container - NOT 'form' $("body").layout(); }); </head> <body> <form><!-- a child of body, and the 1st form --> <div class="ui-layout-north"> <div class="ui-layout-center"> <div class="ui-layout-west"> </form> <form><!-- a child of body, and the 2nd form --> <!-- these divs will be IGNORED! --> <div class="ui-layout-north"> <div class="ui-layout-center"> <div class="ui-layout-west"> </form> </body>Example: ID-selectors allow panes to be deeply nested:
$(document).ready(function() { // panes only need to be 'descendants' of container $("body").layout({ // using custom 'ID' paneSelectors north__paneSelector: "#north" , west__paneSelector: "#west" , center__paneSelector: "#center" }); }); </head> <body> <form><!-- nested inside a form --> <div><!-- nested a 2nd level --> <div><!-- nested a 3rd level --> <div id="north"> <div id="center"> <div><!-- nested a 4th level! --> <div id="west"> </div> </div> </div> </form> </body>Example: Using different selectors/features together:
$(document).ready(function() { $("body").layout(); /* east & west panes require 'ID' selectors because they are 'nested inside a div' */ west__paneSelector: "#west" , east__paneSelector: "#east" /* north & south panes are 'children of body' default-selectors shown just for reference */ , north__paneSelector: ".ui-layout-north" , south__paneSelector: ".ui-layout-center" */ /* center pane is a 'child of the first form' default-selector shown just for reference */ , center__paneSelector: ".ui-layout-center" }); }); </head> <body> <!-- 'north' & 'south' are children of body --> <div class="ui-layout-north"> <div class="ui-layout-south"> <!-- 'center' is nested inside a form --> <form> <div class="ui-layout-center"> </form> <!-- 'east' & 'west' are nested inside a div --> <div> <div id="west"> <div id="east"> </div> </body>
Selector string for INNER div/element. This div will auto-size so only it scrolls, and not the entire pane.Same class-name could be used for divs inside all panes.
SEE Content-Scrolling below for more information.
Selector string for INNER divs/elements. These elements will be 'ignored' when calculations are done to auto-size the content element. This may be necessary if there are elements inside the pane that are absolutely-positioned and intended to 'overlay' other elements.Same class-name could be used for elements inside all panes
Used for auto-generated classNames for each 'layout pane':// default classes applied to the 'west pane' class="ui-layout-pane ui-layout-pane-west ui-layout-pane-open ui-layout-pane-west-open"The last two classes change when the pane is closed:
class="... ui-layout-pane-closed ui-layout-pane-west-closed"
Used for auto-generated classNames for each 'resizer-bar':class="ui-layout-resizer ui-layout-resizer-west ui-layout-resizer-open ui-layout-resizer-west-open"The last two classes change when the pane is closed:
class="... ui-layout-resizer-closed ui-layout-resizer-west-closed"If the pane was 'slid open', 2 additional classes are generated:
class="... ui-layout-resizer-sliding ui-layout-resizer-west-sliding"When a pane is 'resized', the 'real resizer-bar' gets 2 additional classes:
class="... ui-layout-resizer-drag ui-layout-resizer-west-drag"The 'cloned resizer-bar' – which is actually 'dragged' – gets 2 different styles:
class="... ui-layout-resizer-dragging ui-layout-resizer-west-dragging"See Classes Added During Resizing for more information.
Used for auto-generated classNames for each 'toggler-button':class="ui-layout-toggler ui-layout-toggler-open ui-layout-toggler-west ui-layout-toggler-west-open"The last two classes change when the pane is closed:
class="... ui-layout-toggler-closed ui-layout-toggler-west-closed"The toggler is 'inside' the resizer, so can also be accessed using those classes:
/* CSS Rule - hide toggler while resizing */ .ui-layout-resizer-drag ui-layout-toggler { display: none; }
This is used as a prefix when generating classNames for 'custom buttons'.
(Do not confuse with normal 'toggler-buttons')FIRST, the 'type' (action) of the button is appended:
- ui-layout-button-toggle
- ui-layout-button-open
- ui-layout-button-close
- ui-layout-button-pin
THEN, the 'pane name' of the button is appended, like:
- ui-layout-button-toggle-west
- ui-layout-button-open-south
Here are the generated styles for a custom 'close-button' for the 'west-pane':
class="ui-layout-button-close ui-layout-button-close-west"Pin-buttons have additional classes added for 'pin-up' and 'pin-down' states:
class="ui-layout-button-pin ui-layout-button-pin-west ui-layout-button-pin-up ui-layout-button-pin-west-up"The last two classes change when the pane is 'pinned' (open):
class="... ui-layout-button-pin-down ui-layout-button-pin-west-down"SEE Creating Custom Toggler Buttons for more info.
Specifies the initial size of the panes - 'height' for north & south panes - 'width' for east and west. If "auto", then pane will size to fit its content - most useful for north/south panes (to auto-fit your banner or toolbar), but also works for east/west panes.You normally will want different sizes for the panes, but a 'default size' can be set
Minimum-size limit when resizing a pane (0 = as small as pane can go)
Maximum-size limit when resizing a pane (0 = as large as pane can go)
Spacing between pane and adjacent pane - when pane is 'open' or 'closed'
Tip when resizer-bar can be 'dragged' to resize a pane
This is the cursor when the mouse is over the 'resizer-bar'. However, if the mouse is over the 'toggler-button' inside the resizer bar, then the cursor is a 'pointer' - ie, the togglerCursor instead of the resizerCursor.
Opacity of resizer bar when 'dragging' to resize a pane.This value is passed to the ui.draggable widget
Leave this set to '1' if you want to use CSS to control opacity. Otherwise you must use !important to override the specified opacity.
When enabled, layout will 'mask' iframes on the page when the resizer-bar is 'dragged' to resize a pane. This solved problems related to dragging an element over an iframe.If desired, you can mask only specific iframes and/or only when specific panes are resized:
// mask ALL iframes when ANY pane is resized $('body').layout({ maskIframesOnResize: true }); // mask specific iframes when specific panes are resized $('body').layout({ west__maskIframesOnResize: "#iframe1, #iframe2" , east__maskIframesOnResize: ".ui-layout-pane iframe" });The mask is a DIV with the classui-layout-maskBy default the DIV is transparent, but it can be give am overlay effect by adding color and opacity:
/* CSS Rule - give iframe-mask shading */ .ui-layout-mask { background-color: #666; opacity: 0.1; filter: alpha(opacity=10); /* for IE */ }
Tip when the resizer-bar will trigger 'sliding open'
Cursor when resizer-bar will trigger 'sliding open' - ie, when pane is 'closed'
Trigger events to 'slide open' and 'slide closed' a pane
Tip on toggler when pane is 'open' or 'closed'.
Length of toggler-button when pane is 'open' or 'closed'.Length means 'width' for north/south togglers, and 'height' for east/west togglers.
"100%"OR-1means 'full height/width of resizer bar' - 0 means 'hidden'
If true, the toggler-button is hidden when a pane is 'slid-open'. This makes sense because the user only needs to 'mouse-off' to close the pane.You could set this 'false' and use CSS to do the same thing:
/* CSS Rule - hide toggler when sliding-open */ .ui-layout-resizer-sliding ui-layout-toggler { display: none; }
Alignment of toggler button inside the resizer-bar when pane is 'open' or 'closed'.A positive integer means a pixel offset from top or left
A negative integer means a pixel offset from bottom or right
Position-Keywords: "left", "center", "right", "top", "middle", "bottom"
Usually a background-image is set in CSS to customize a toggler-button. However, you can also put text inside a toggler by using these options. The text is wrapped in a SPAN, which is then added inside the toggler DIV. The SPAN classes identify them as either 'open' or 'closed' content:$('body').layout({ west__togglerContent_open: "‹" // "‹" , west__togglerContent_closed: "›" // "›" , east__togglerContent_open: "›" // "›" , east__togglerContent_closed: "‹" // "‹" }); // would generates this HTML for the west-toggler <SPAN class="... ui-layout-toggler-west ... "> <SPAN class="content content-open">‹</SPAN> <SPAN class="content content-closed">›</SPAN> </SPAN>You MUST add CSS to format the toggler-text or else it will only be '1px'!
/* format the text inside the toggler */ .ui-layout-toggler .content { font-size: 12px; /* IMPORTANT: default = 1px */ font-weight: bold; text-align: center; }NOTE: If you want a background-color or border on the toggler-button, set it on the 'toggler' element - NOT on the toggler 'content' element.
The inner text-span will be automatically centered inside the toggler button.
If 'true', then 'cursor hotkeys' are enabled. Can be set per-pane if desired.These default hotkeys cannot be changed - only enabled or disabled.
The cursor/arrow key must be pressed in combination with CTRL -or- SHIFT
- Toggle North-pane: CTRL+Up or SHIFT+Up
- Toggle South-pane: CTRL+Down or SHIFT+Down
- Toggle West-pane: CTRL+Left or SHIFT+Left
- Toggle East-pane: CTRL+Right or SHIFT+Right
The SHIFT+ARROW combinations are ignored if pressed while the cursor is in a form field, allowing users to 'select text' — eg: SHIFT+Right in a TEXTAREA
Custom hotkeys must be pressed in combination with either the CTRL or SHIFT key - or both together. Use this option to choose which modifier-key(s) to use with the customHotKey.If this option is missing or invalid, "CTRL+SHIFT" is assumed.
NOTE: The ALT key cannot be used because it is not detected by some browsers.
If a hotkey is specified, it is automatically enabled. It does not matter whether 'cursor hotkeys' are also enabled – those are separate.You can specify any of the following values:
- letter from A to Z
- number from 0 to 9
- Javascript charCode value for the key
The customHotkeys option must be set separately for each pane, but the customHotkeyModifier option can be set once, as the 'default' for all panes.
Animation effect for open/close. Choose a preset effect OR can specify a custom fxName as long as you also specify fxSettings (even if fxSettings is just empty - {})
Speed of animations – standard jQuery keyword like 'fast', or a millisecond value.
You can customize the default animation settings by passing new settings, like:$("body").layout({ fxName: "slide" , fxSettings: { duration: 500, easing: "bounceInOut" } });If a non-standard effect is specified, then fxSettings is REQUIRED (can be 'empty' though)$("body").layout({ fxName: "blind" , speed: 1000 // optional , north__fxSettings: { direction: "vertical" } , west__fxSettings: { direction: "horizontal" } , east__fxSettings: {} // empty fxSettings is still valid! });It's also possible to extend the 'default' layout effects by passing a special key:
$("body").layout({ effects: { // MODIFY a standard effect slide: { all: { duration: 500, easing: "bounceInOut" } } // ADD a new effect , blind: { all: {} , north: { direction: "vertical" } , south: { direction: "vertical" } , east: { direction: "horizontal" } , west: { direction: "horizontal" } } } });You MUST use the sub-key option format to update default effects.
(This will change when Layout is updated to the UI widget API)
If 'true', then pane is 'closed' when layout is created
If 'true', then pane is 'hidden' when layout is created - no resizer or spacing is visible, as if the pane does not exist!
Callback function name - activate when pane is 'closed'SEE Using Callback Functions below.
Callback function name - activate when pane is 'closed'SEE Using Callback Functions below.
Callback function name - activate when pane is 'opened'SEE Using Callback Functions below.
Callback function name - activate when pane is 'closed'SEE Using Callback Functions below.
Callback function name - activate when pane is 'resized' - either manually or as a result of the container resizing.SEE Using Callback Functions below.
As of version 1.1.1, a 'state' object was added to UI Layout. This hash object contains the 'current dimensions' for all panes, plus logic-vars indicating each pane's 'current state'. For example: Is the west pane open or closed? What is its current size?
This object is exposed as a 'state' property (eg: myLayout.state) so it can be read by custom code. All state properties are READ-ONLY
All state data must be referenced 'by pane'. Most logic-vars (eg: isClosed) apply only to 'border panes'.
var state = myLayout.state; // current state var isWestPaneOpen = !state.west.isClosed; var isSouthPaneHidden = state.south.isHidden; var isEastPaneSliding = state.east.isSliding; // current dimensions var westCurrentSize = state.west.size; var westMinimumSize = state.west.minSize; var containerInnerWidth = state.container.innerWidth; var containerPaddingLeft = state.container.paddingLeft;
State functionality is not yet finished.
Eventually a complete set of dimensions, including padding and borders, will be available for ALL panes, including the center. Details on this will be added here when it is complete.
In the meantime, you can measure the panes youself if needed.
Is the pane 'closed'? If not closed, then could be EITHER 'open normally' OR 'sliding open'.
When a pane is 'sliding', it was opened by sliding over-top of other panes. The pane is 'open', but only temporarily - until the user moves their mouse off.This is different from when a pane is 'opened normally', and becomes fixed in place, and all adjacent panes are resized.
When isSliding=true, isClosed=false - when it slides closed again, isClosed=true.
When a pane is 'opened normally', isClosed=false AND isSliding=false.
This is only true when the user is in the process of 'dragging' the resizer bar.
A 'hidden pane' is not the same as a 'closed pane'. When a pane is hidden, it is as if it does not exist - there is no resizer-bar or toggler-button visible, and the 'pane spacing' collapses.So if a pane is hidden, you must have some other way to make it visible again. This means a custom button or some other custom code that calls the show() command.
When there is 'not enough room' for a pane to be displayed, it is automatically hidden. In this case, isHidden=true AND noRoom=true.This is different than hiding a pane using the hide() command, because when there is enough room for the pane to appear (by resizing or closing a pane), the hidden pane will reappear automatically.
This is the only logic var that also applies to the 'center-pane'.
The state.PANE.size property is the 'current size'. This is different from options.PANE.size, which was the 'initial size' specified when the layout was created.
Numerous size values are available, including minSize & maxSize. These are constantly updated based on the layout's current state. (You can read the initial minSize/maxSize from 'layout.options')
The state pane-size can be combined with state-logic data when 'saving the current layout state'.
SEE State Management on the Tips & Tricks page for an example of how 'layout state' can be persisted.
Callbacks can be set for open, close and resize events for each pane. The callback option can be:
There are 5 types of pane-events that will trigger a callback:
EACH type of pane-event has 3 callback options, for example:
The 'start' callback fires BEFORE the event starts, so 'onopen_start' fires before the pane starts to open.
If a 'start' callback function returns 'false', the event will be cancelled.
$("body").layout({ onopen_start: function () { // STOP the pane from opening return false; // false = Cancel } });
NOTE: If an event is 'automatically triggered' by layout logic – like closing a pane when there is insufficient room – then the event cannot be cancelled. In this case, returning false will have no effect.
The 'end' callback fires AFTER the event completes. So onopen_end will fire after the pane has opened, including the completion of all animations.
Callback options without a suffix are really 'end' callbacks, so onopen is the same as onopen_end. These options exist for backwards compatibility, and for simpler code, since most of the time it will be the 'end' callbacks you will use.
NOTE: If BOTH 'onopen' and 'onopen_end' options are set, the 'onopen_end' option takes precidence and the 'onopen' option is ignored.
Five parameters are automatically returned to all callback functions, in this order:
When a layout is created, numerous CSS class-names are added to the original 'pane' elements, as well as the generated 'resizer-bar' and 'toggler-button' elements.
These options are used to set the 'base' class-names (default values shown):
paneClass: "ui-layout-pane" resizerClass: "ui-layout-resizer" togglerClass: "ui-layout-toggler"
Each of the 3 element types - panes, resizers and togglers - has multiple class-names generated based on these options. Some classes change to indicate on whether the pane is open or closed. This comprehensive set of auto-generated classes make it easy for CSS rules to target all the elements as a group, specifically, and by 'state' (open/closed).
Here are classes for all 'west' elements, using the default class-names:
Pane Element (hard-coded DIV or IFRAME)
This is the result when the auto-generated classes are added to the west pane:
<div class="ui-layout-pane ui-layout-pane-west ui-layout-pane-open ui-layout-pane-west-open">
When the pane is 'closed', the last two classes CHANGE:
<div class="... ui-layout-pane-closed ui-layout-pane-west-closed">
NOTE: Each pane must have a unique 'paneSelector' in the HTML markup. The default selector is a class-name, eg:<div class="ui-layout-west">. However, an ID or other class-name could be used instead, so to avoid confusion with the auto-generated classes, the "ui-layout-west" class-name is NOT INCLUDED in the code samples above.
Resizer Element (auto-generated DIV)
This is the result when the auto-generated classes are added to the west resizer:
<div class="ui-layout-resizer ui-layout-resizer-west ui-layout-resizer-open ui-layout-resizer-west-open">
When the pane is 'closed', the last two classes CHANGE:
<div class="... ui-layout-resizer-closed ui-layout-resizer-west-closed">
If a pane is 'slid open' - instead of being opened normally - two additional classes are generated:
So this is the complete set of classes when the west pane is 'slid open':
<div class="ui-layout-resizer ui-layout-resizer-west ui-layout-resizer-open ui-layout-resizer-west-open ui-layout-resizer-sliding ui-layout-resizer-west-sliding">
These extra classes allow the resizer-bar to be styled differenty when a pane is 'sliding'. For example, the resizer-bar could be grey when the pane is 'open' normally, but transparent if it is 'slid open'.
Toggler Element (auto-generated DIV)
This is the result when the auto-generated classes are added to the west toggler:
<div class="ui-layout-toggler ui-layout-toggler-west ui-layout-toggler-open ui-layout-toggler-west-open">
When the pane is 'closed', the last two classes CHANGE:
<div class="... ui-layout-toggler-closed ui-layout-toggler-west-closed">
Using the default classes makes it easy to apply a 'layout theme'. However, if there is more than one layout on a page, you may want to change the class-name for one of them so each layout can have different CSS - for example: The complex demo uses custom class-names for the 'outer layout' to differentiate it from the 'inner layout', which uses the default class-names.
When a pane is being "resized", a clone of the resizer-bar is created by ui.draggable. During the dragging process, classes are added to both the real resizer-bar (which does not move) and the cloned resizer-bar (which is 'dragging'). When dragging is completed, the cloned element is deleted, the real resizer-bar is moved to the new position, and the 'drag' classes are removed.
These are the classes added to the west-pane elements while resizing is in-progress:
REAL Resizer-bar
The 'drag' classes are added to the 4 regular classes already on the resizer bar
class="ui-layout-resizer ui-layout-resizer-west ui-layout-resizer-open ui-layout-resizer-west-open ui-layout-resizer-drag ui-layout-resizer-west-drag"
CLONED Resizer-bar
The cloned bar inherits the 4 regular classes from the real resizer-bar - the 'dragging' classes are added to these:
class="ui-layout-resizer ui-layout-resizer-west ui-layout-resizer-open ui-layout-resizer-west-open ui-draggable-dragging ui-layout-resizer-dragging ui-layout-resizer-west-dragging"
To use graphics for resizer-bars and toggler-buttons, specify them as background-images in your CSS. Different graphics and/or opacity can be specified for each 'state' - open, closed, resizing and hover (using the :hover pseudo-class).
The complex demo uses a variety of colors, images and opacity to create a range of effects. Pane-spacing can also be used to control appearance. Each pane can have different options and be styled independant of the others.
If you add custom buttons using the layout utilities described below, a number of additional styles are auto-generated for the button-elements.
SEE Special Utility Methods below for a list of the button classes.
If an ID is specified as a 'paneSelector', then the generated resizer-bar and toggler-button for that pane are automatically given corresponding IDs, for example...
If these options are used when creating a layout...
layout({ north__paneSelector: "#header" , west__paneSelector: "#Menu" });
The associated resizer and toggler elements will be given a similar ID - by appending "-resizer" or "-toggler" to the ID of the 'pane'...
// resizer & toggler for the NORTH ('header') pane <div id="header-resizer" class="..."> <div id="header-toggler" class="..."></div> </div> // resizer & toggler for the WEST ('menu') pane <div id="Menu-resizer" class="..."> <div id="Menu-toggler" class="..."></div> </div>
NOTE: This does not affect the auto-generated 'class-names' added to the elements.
There are 2 options for this feature (class-names shown are defaults):
When initializing a pane, the layout code searches for:$Pane.children(s.contentSelector). If a content element is found (usually a div or an iframe), it will be auto-sized to fill the vertical space not used by other child-elements. If the space is not enough to display all the content, then the content element will 'scroll'.
This makes all elements above the content element look like a 'header', and everything below like a 'footer'. All this is done by just dynamically resizing the content element - there is no special CSS, and no other elements are touched.
The content element can have unlimited siblings - header, subheader, footer, etc. The code loops through all other elements to calculate the height that remains to fit the content element. If there is not enough room, the content element is completely hidden.
To exclude an element(s) from the height calculations - like an absolutely positioned element - add a selector for it/them in thecontentIgnoreSelectoroption. Anything matching this selector is 'ignored' when measuring.
The content element is resized every time the pane containing it is resized or opened. You can also manually trigger a resize from your own code using the resizeContent() method, eg:
myLayout.resizeContent("west");
A number of utility methods are provided to integrate custom buttons and other code with your layout. These utilities are available as 'methods' of the layout instance.
All sample code below assumes the layout-instance is assigned to 'myLayout', like so:
var myLayout = $("body").layout();
Custom buttons can be hard-coded in HTML by using basic layout methods:
<button onclick="myLayout.toggle('west')"> Toggle West Pane</button> <img onclick="myLayout.open('west')" src="img/open_button.gif"> <span onClick="myLayout.close('west')> Close West Pane</span>
SEE the simple demo for samples of hard-coded buttons.
These 3 utilities provide another way to create buttons to open and close panes. First create the element(s) to use as a button, then call the utility you want and pass these parameters:
- selector - a jQuery selector string to access the button element(s)
- pane - the pane the button is to control: "north", "south", "east" or "west"
Location does not matter, so a button in the north-pane (eg, a toolbar) can toggle the east-pane (eg, a help-panel).
Examples using 'ID' and 'class' selectors for button-elements:
addOpenBtn("#tbarShowHelpButton", "east"); addToggleBtn(".ui-layout-pane-north .custom-toggle-button" , "west");Two classes are automatically added to the button-element, based on the buttonClass option, which has a default value of "ui-layout-button":
- ui-layout-button-ACTION
- ui-layout-button-ACTION-PANE
Examples for each type of button - assumes buttons control the 'west pane':
class="ui-layout-button-toggle ui-layout-button-toggle-west" class="ui-layout-button-close ui-layout-button-close-west" class="ui-layout-button-open ui-layout-button-open-west"SEE the complex demo - the square 'close' buttons in the east/west panes utilize these utilities.
This utility makes an element act like a 'pin button' a common and intuitive interface device.
SEE the complex demo to see how pin-buttons work.
Classes similar to the utilities above are added, plus two additional classes to indicate the 'current state' of the pin (up/down):
- ui-layout-button-pin
- ui-layout-button-pin-west
- ui-layout-button-pin-up
- ui-layout-button-pin-west-up
When the pin is 'down' (pinned), the last two classes change to:
- ui-layout-button-pin-down
- ui-layout-button-pin-west-down
These classes can be used to change the background-image via CSS, as is done in the complex demo.
When a layout is created, each pane becomes a container for all the elements inside it. Elements that need to 'popup', like a dialog box, should be put in the 'body' of the page - not inside one of the panes. This allows the popup to overlay all the panes.
However, sometimes a popup or drop-down (like a 'menu') needs to originate from inside a pane. For example, the north-pane may hold a toolbar with drop-down menus that need to appear over-top of the panes below. For this to work, the pane containing the drop-down element must:
NOTE: The z-index of the popup element itself is irrelevant outside the pane. It is the pane that contains the popup element that must be 'above' the adjacent panes. Since pane-animations change their z-indexes, setting z-index in your CSS will not work.
If you have a layout where only 1-pane has popups, then just put that pane 'last' in your HTML mark-up, and give it the style: 'overflow: visible'. This will make all popups and drop-downs from that pane work normally.
However, if you have a layout with drop-downs or popups in multiple panes, then this pair of layout utilities provide a solution...
The allowOverflow utility raises a pane's z-index so popups work properly.
The 'elem_or_pane' parameter can be either:
- The 'pane element', or a 'decendant element' of the pane, that contains the popup, or
- The 'name' of the pane containing the popup, ie: "north", "south", "east", "west" or "center"
The resetOverflow utility puts the pane back to its normal z-index. It accepts the same parameter as allowOverflow, and should be called when the popup closes. However, when allowOverflow is called, all other panes are automatically reset anyway.
Examples:
// using a 'list' mouse-over event <ul onmouseover="myLayout.allowOverflow(this)" onmouseout="myLayout.resetOverflow(this)"> // using the 'pane' mouse-over event <div class="ui-layout-north" onmouseover="myLayout.allowOverflow(this)")> // called from the code that initiates a popup myLayout.allowOverflow('north'); showMyPopup();The allowOverflow method can also be automatically attached to panes using the showOverflowOnHover option. This makes things more automatic, but there are some scenarios where you need to control this from in your code.
SEE the simple demo for working examples of pop-ups and drop-downs.
NOTE: Using allowOverflow on a 'scrolling pane' causes the scrollbar to disappear and the pane contents to 'overflow' on top of the pane below. This can be seen by hovering the pop-up in the East pane of the simple demo.