Panel Widgetversion added: 1.3
Description: Creates a panel widget
Panels are designed to be as flexible as possible to make it easy to create menus, collapsible columns, drawers, inspectors panes and more.
Where panel markup goes in a page
A panel must be a sibling to the header, content and footer elements inside a jQuery Mobile page. You can add the panel markup either before or after these elements, but not in between. A panel cannot be placed outside a page, but this constraint will be removed in a future version.
Here is an example of the panel before the header, content and footer in the source order:
1
2
3
4
5
6
7
8
9
10
11
|
|
Alternately, it's possible to add the panel markup after the header, content and footer in the source order, just before the end of the page container. Where in the source order you place the panel markup will depend on how you want to page content to read for people experiencing the page in a C-grade device (HTML only) or for a screen reader.
If a page contains a panel the framework wraps the header, content and footer sections in a div
. When opening a panel with display mode "reveal" or "push" the transition is applied to this wrapper. An exception is fixed headers and footers. Those are not included in the wrapper, but will transition in sync with it. Be aware of the fact that all your visible page content should live inside those page sections.
CSS Multi-column Layout
To avoid blinks when opening a panel, we force hardware acceleration on WebKit browsers. The CSS that is used to do this can cause issues with buttons and form elements on the page if their container has a CSS multi-column layout (column-count
). To resolve this you have to set the following rule for the element or its container:
1
|
|
Panel markup conventions
A panel consists of a container with a data-role="panel"
attribute and a unique ID
. This ID
will be referenced by the link or button to open and close the panel. The most basic panel markup looks like this:
1
2
3
|
|
The position of the panel on the screen is set by the data-position
attribute. The position defaults to left
, meaning it will appear from the left edge of the screen. Specify data-position="right"
for it to appear from the right edge instead.
The display mode of the panel is set by the data-display
attribute. The defaults to reveal
, meaning the panel will sit under the page and reveal as the page slides away. Specify data-display="overlay"
for the panel to appear on top of the page contents. A third mode, data-display="push"
animates both the panel and page at the same time.
Here is an example of a panel with a custom position and display option set:
1
2
3
|
|
Dynamic content
When you dynamically add content to a panel or make hidden content visible while the panel is open, you have to trigger the updatelayout
event on the panel.
1
|
|
The framework will check the new height of the panel contents and, in case this exceeds the screen height, set the page min-height
to this height and unfix panels with data-position-fixed="true"
. See also Panel positioning.
Opening a panel
A panel's visibility is toggled by a link somewhere on the page or by calling the panel's open
method directly. The defaults place the panel on the left in "reveal" mode. Open a panel programmatically like this:
1
|
|
To control a panel from a link, point the href
to the ID
of the panel you want to toggle (mypanel
in the example below). This instructs the framework to bind the link to the panel. This link will toggle the visibility of the panel so tapping it will open the panel, and tapping it again will close it.
1
|
|
Closing a panel
Clicking the link that opened the panel, swiping left or right, or tapping the Esc key will close the panel. To turn off the swipe-to-close behavior, add the data-swipe-close="false"
attribute to the panel.
By default, panels can also be closed by clicking outside the panel onto the page contents. To prevent this behavior, add the data-dismissible="false"
attribute to the panel. It's possible to have the panel and page sit side-by-side at wider screen widths and prevent the click-out-to-close behavior only above a certain screen width by applying a media query. See the responsive section below for details.
A panel can also be closed by calling the panel's close
method directly.
1
|
|
It's common to also add a close button inside the panel. To add the link that will close the panel, add the data-rel="close"
attribute to tell the framework to close that panel when clicked. It's important to ensure that this link also makes sense if JavaScript isn't available, so we recommend that the href
points to the ID of the page to which the user should jump when closing. For example, if the button to open the panel is in the header bar that has and ID of my-header
, the close link in the panel should be:
1
|
|
Panel animations
Panels will animate if the browser supports 3D transforms. The presence of such support is established by the same criteria for CSS animation support we use for page transitions. Panel animations use translateX
CSS transforms to ensure they are hardware accelerated and smooth.
The framework has a feature test to detect if the required CSS properties are supported and will fall back to a simple hide/show if not available. After thorough testing, we decided to not animate panels on less capable platforms because the choppier animations weren't a better experience than a simple hide/show.
The animate
option allows you to turn off panel animations for all devices. To turn off animations via markup, add the data-animate="false"
attribute to the panel container.
The use of hardware acceleration is triggered during initialization of the page to prevent blinks when opening a panel. Because this increases memory use you have to be aware of performance issues if you use long lists or scripts to dynamically inject content on a page with an animated panel.
Panel positioning
The panel will be displayed with the position:absolute
CSS property, meaning it will scroll with the page. When a panel is opened the framework checks to see if the bottom of the panel contents is in view and, if not, scrolls to the top of the page.
You can set a panel to position:fixed
, so its contents will appear no matter how far down the page you're scrolled, by adding the data-position-fixed="true"
attribute to the panel. The framework also checks to see if the panel contents will fit within the viewport before applying the fixed positioning because this property would prevent the panel contents from scrolling and using overflow
is not well supported enough to use at this time. If the panel contents are too long to fit within the viewport, the framework will simply display the panel without fixed positioning.
In general, we recommend that you place the buttons that open the panel at the very top of the screen which is the most common UI pattern for panels. This will avoid the need to scroll and also makes the transitions a bit smoother.
Note that there are issues with fixed positioning within Android WebView applications (not the browser) that can cause layout issues, especially when hardware acceleration isn't enabled. We recommend not to use the fixed position panel option if deploying to an Android app. Also, if you have a fixed panel on a page with fixed toolbars, the toolbars might not transition together with the page content.
Styling panels
By default, panels have very simple styles to let you customize them as needed. Panels are essentially just simple blocks with no margins that sit on either side of the page content. The framework wraps the panel content in a div
with class ui-pannel-inner
which has a padding of 15 pixels. If needed you can override this with custom CSS or use option classes.panelInner
to set a different class name for the div
Panels have a fixed width of 17em (272 pixels) which is narrow enough to still show some of the page contents when open to make clicking out to close easy, and still looks good on wider tablet or desktop screens. The styles to set widths on panels are fairly complex but these can be overridden with CSS as needed.
Note that adding padding, borders, or margins directly to the panel container will alter the overall dimensions and could cause the positioning and animation to be affected. To avoid this, apply styles to the panel content wrapper (.ui-pannel-inner
).
Other than the theme background, width and 100% height styles, panels have very little styling on their own. The default theme for panels is "c". You can set a different theme for the panel by adding a data-theme
to the panel container, or set data-theme="none"
and add your own classes to style it as needed.
The framework applies the theme that is used for the page to the content wrapper. Before opening a panel that has display mode reveal or push, the page theme will be set to the same theme that is used for the panel. This is done to mask that most mobile browsers haven't finished painting the panel background when the animation to open it has already started. If you use a background image for a page, you have to set it for the ui-body-*
class of the theme that you use for the page so it will be used as background of the content wrapper.
Making the panel responsive
When the push or reveal display is used, a panel pushes the page aside when it opens. Since some of the page is pushed offscreen, the panel is modal and must be closed to interact with the page content again. On larger screens, you may want to have the panel work more like a collapsible column that can be opened and used alongside the page to take better use of the screen real estate.
To make the page work alongside the open panel, it needs to re-flow to a narrower width so it will fit next to the panel. This can be done purely with CSS by adding a left or right margin equal to the panel width (17em) to the page contents to force a re-flow. Second, the invisible layer placed over the page for the click out to dismiss behavior is hidden with CSS so you can click on the page and not close the menu.
Here is an example of these rules wrapped in a media query to only apply this behavior above 35em (560px):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
|
Applying a preset breakpoint
Included in the widget styles is a breakpoint preset for this behavior that kicks in at 55em (880px). This breakpoint is not applied by default to make it easier for you to write custom breakpoints that work best for your content and design. To apply the breakpoint preset, add the ui-responsive-panel
class to the page wrapper (not the panel).
Options
animateType: Boolean
true
This option is also exposed as a data attribute:data-animate="false"
on the panel container.
Initialize the panel with the animate
option specified:
1
|
|
Get or set the animate
option, after initialization:
1
2
3
4
5
|
|
classes.animateType: String
"ui-panel-animate"
true
.classes.contentFixedToolbarType: String
"ui-panel-fixed-toolbar-wrap"
classes.contentFixedToolbarClosedType: String
"ui-panel-content-fixed-toolbar-closed"
classes.contentFixedToolbarOpenType: String
"ui-panel-content-fixed-toolbar-open"
classes.contentWrapType: String
"ui-panel-content-wrap"
classes.contentWrapClosedType: String
"ui-panel-content-wrap-closed"
classes.contentWrapOpenType: String
"ui-panel-content-wrap-open"
classes.modalType: String
"ui-panel-dismiss"
classes.modalOpenType: String
"ui-panel-dismiss-open"
classes.pagePanelType: String
"ui-page-panel"
classes.pagePanelOpenType: String
"ui-page-panel-open"
classes.panelFixedType: String
"ui-panel-fixed"
classes.panelInnerType: String
"ui-panel-inner"
classes.panelOpenType: String
"ui-panel-open"
dismissibleType: Boolean
true
This option is also exposed as a data attribute:data-dismissible="false"
on the link that opens the panel.
Initialize the panel with the dismissible
option specified:
1
|
|
Get or set the dismissible
option, after initialization:
1
2
3
4
5
|
|
displayType: String
"reveal"
This option is also exposed as a data attribute:data-display="push"
on the link that opens the panel.
Initialize the panel with the display
option specified:
1
|
|
Get or set the display
option, after initialization:
1
2
3
4
5
|
|
initSelectorType: CSS selector string
":jqmData(role='panel')"
1
2
3
|
|
positionType: String
"left"
This option is also exposed as a data attribute:data-position="right"
on the link that opens the panel.
Initialize the panel with the position
option specified:
1
|
|
Get or set the position
option, after initialization:
1
2
3
4
5
|
|
positionFixedType: Boolean
false
This option is also exposed as a data attribute:data-position-fixed=true
on the panel.
Initialize the panel with the positionFixed
option specified:
1
|
|
Get or set the positionFixed
option, after initialization:
1
2
3
4
5
|
|
swipeCloseType: Boolean
true
This option is also exposed as a data attribute:data-swipe-close=false
on the panel.
Initialize the panel with the swipeClose
option specified:
1
|
|
Get or set the swipeClose
option, after initialization:
1
2
3
4
5
|
|
themeType: String
"c"
Possible values: swatch letter (a-z).
This option is also exposed as a data attribute: data-theme="a"
.
Initialize the panel with the theme
option specified:
1
|
|
Get or set the theme
option, after initialization:
1
2
3
4
5
|
|
Methods
close()Returns: jQuery (plugin only)
- This method does not accept any arguments.
Invoke the close method:
1
|
|
open()Returns: jQuery (plugin only)
- This method does not accept any arguments.
Invoke the open method:
1
|
|
toggle()Returns: jQuery (plugin only)
- This method does not accept any arguments.
Invoke the toggle method:
1
|
|
Events
beforeclose( event, ui )Type: panelbeforeclose
Note: The ui
object is empty but included for consistency with other events.
Initialize the panel with the beforeclose callback specified:
1
2
3
|
|
Bind an event listener to the panelbeforeclose event:
1
|
|
beforeopen( event, ui )Type: panelbeforeopen
Note: The ui
object is empty but included for consistency with other events.
Initialize the panel with the beforeopen callback specified:
1
2
3
|
|
Bind an event listener to the panelbeforeopen event:
1
|
|
close( event, ui )Type: panelclose
Note: The ui
object is empty but included for consistency with other events.
Initialize the panel with the close callback specified:
1
2
3
|
|
Bind an event listener to the panelclose event:
1
|
|
create( event, ui )Type: panelcreate
Note: The ui
object is empty but included for consistency with other events.
Initialize the panel with the create callback specified:
1
2
3
|
|
Bind an event listener to the panelcreate event:
1
|
|
open( event, ui )Type: panelopen
Note: The ui
object is empty but included for consistency with other events.
Initialize the panel with the open callback specified:
1
2
3
|
|
Bind an event listener to the panelopen event:
1
|
|
Example:
A basic example of a panel.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
|