Widgets are feature-rich, stateful plugins that have a full life-cycle, along with methods and events. Check out the widget factory documentation for more details.
$.mobile.widget) is deprecated as of 1.4 and will be removed in 1.5. It is now sufficient to base your custom jQuery Mobile widgets on the jQuery UI widget factory itself. This means that in your call to $.widget() you can omit the base altogether.
$.widget( "my.widget", /* NOTE: no base needed */ {
options: {
/* ... */
},
_create: function() {
/* ... */
}
/* ... */
});
jQuery Mobile offers several custom events that build upon native events to create useful hooks for development.
jQuery Mobile exposes several methods on the $.mobile object for use in your applications.
A collection of methods for dealing with paths.
jQuery Mobile offers CSS-based enhancements for common user interface elements.
jQuery Mobile offers a set of built-in icons that can be applied to buttons, collapsibles, listview buttons and more.
jQuery Mobile exposes several properties on the $.mobile object for use in your applications.
The jQuery Mobile framework uses HTML5 data- attributes to allow for markup-based initialization and configuration of widgets.
The jQuery UI button widget is bundled in jQuery Mobile with some changes. Thus, its API documentation fully describes its functionality.
The jQuery UI checkboxradio widget is bundled in jQuery Mobile with some changes. Thus, its API documentation fully describes its functionality.
jQuery Mobile uses the following style classes:
ui-corner-all |
Adds rounded corners to the element. |
ui-shadow |
Adds an item shadow around the element. |
ui-overlay-shadow |
Adds an overlay shadow around the element. The intended effect is for the element to appear to float above other elements. |
ui-mini |
Reduces the font size and scales down paddings proportionally to produce a miniature version of the element for use in toolbars and tight spaces. |
These classes can be applied any of the framework's widgets.
ui-collapsible-inset |
The collapsible widget has horizontal margins, borders, and rounded corners when this class is applied. |
ui-listview-inset |
The listview widget has horizontal margins, borders, and rounded corners when this class is applied. |
In addition to the style classes, you can add the following classes to a (anchor) and button elements to render them touch-friendly:
| Basic options | |
|---|---|
ui-btn |
You must add this class to indicate that the element is to be styled as a button. This is a prerequisite for adding any other button-related classes. |
ui-btn-inline |
Displays the button inline. This means that it will only consume as much space as is needed for the label. This allows you to place buttons side by side, flowing with the text. |
ui-shadow-icon |
Draws a shadow around the icon. |
| Icon positioning | |
ui-btn-icon-top |
The icon appears above the text |
ui-btn-icon-right |
The icon appears to the right of the text |
ui-btn-icon-bottom |
The icon appears below the text |
ui-btn-icon-left |
The icon appears to the left of the text |
ui-btn-icon-notext |
The button text is suppressed, and only the icon is shown. The result is a circular button the size of the icon. |
| Theme | |
ui-btn-[a-z] |
Sets the color scheme (swatch) for the button. Use a single letter from a-z that maps to the swatches included in your theme. For example: ui-btn-b |
Icons are used by a variety of widgets. The table below lists all the available icon classes. The widgets which support an icon usually have an option named "icon". The value for that option is the name of the icon, which is appended to the prefix ui-icon- to create the icon class name. In the class list below, the icon names are emphasized as part of the icon class name.
ui-icon-alert |
An exclamation mark inside a triangle. |
ui-icon-arrow-l |
An arrow pointing left (←). |
ui-icon-arrow-r |
An arrow pointing right (→). |
ui-icon-arrow-u |
An arrow pointing up (↑). |
ui-icon-arrow-d |
An arrow pointing down (↓). |
ui-icon-back |
A curved arrow arcing counterclockwise upwards. |
ui-icon-bars |
Three horizontal bars one above the other. |
ui-icon-carat-b |
A carat pointing down (v). |
ui-icon-carat-l |
A carat pointing left (<). |
ui-icon-carat-r |
A carat pointing right (>). |
ui-icon-carat-t |
A carat pointing up (^). |
ui-icon-check |
A checkmark (✓). |
ui-icon-delete |
A diagonal cross similar to (✕). |
ui-icon-edit |
A pencil - similar to (✎) but pointing to the lower left. |
ui-icon-forward |
A curved arrow arcing clockwise upwards. |
ui-icon-gear |
A gear (⚙). |
ui-icon-grid |
A 3✕3 grid. |
ui-icon-home |
A house similar to (⌂). |
ui-icon-minus |
A "minus" sign (-). |
ui-icon-plus |
A "plus" sign (+). |
ui-icon-refresh |
A circular arrow similar to (⟳). |
ui-icon-search |
A magnifying glass. |
ui-icon-star |
A star similar to (✭). |
The class prefixes in the table below are used for applying a swatch to various parts of the user interface. The actual class name is constructed by appending the swatch letter (a-z) to the prefix. For example, the class ui-body-a is the swatch applied to the page.
ui-bar-[a-z] |
Sets the color scheme (swatch) for a bar. This includes headers and footers, or bars you include in the page. |
ui-body-[a-z] |
Sets the color scheme (swatch) for a content block. This includes page content panes (deprecated as of 1.4.0), listview items, popups, collapsibles, the loader widget, sliders, and panels. |
ui-btn-[a-z] |
Sets the color scheme (swatch) for a button. |
ui-group-theme-[a-z] |
Sets the color scheme (swatch) for controlgroups, listviews, and collapsible sets (accordions). |
ui-overlay-[a-z] |
Sets the color scheme (swatch) for backgrounds such as those of popup widgets, and page containers. |
ui-page-theme-[a-z] |
Sets the color scheme (swatch) for pages. |
ui-panel-page-container-[a-z] |
Panels temporarily set the theme on the page container using this class. |
To create a collapsible block of content, create a container and add the data-role="collapsible" attribute. Using the data-content-theme attribute allows you to set a theme for the content of the collapsible.
Directly inside this container, add any header (H1-H6) or legend element. The framework will style the header to look like a clickable button and add a "+" icon to the left to indicate it's expandable.
After the header, add any HTML markup you want to be collapsible. The framework will wrap this markup in a container that will be hidden/shown when the heading is clicked.
By default, the content will be collapsed.
<div data-role="collapsible">
<h3>I'm a header</h3>
<p>I'm the collapsible content. By default I'm closed, but you can click the header to open me.</p>
</div>
This code will create a collapsible widget like this:
The collapsible widget uses the jQuery Mobile CSS framework to style its look and feel. If collapsible specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-collapsible: The outermost container for collapsible. Contains additional classes of ui-collapsible-inset, ui-collapsible-themed-content and ui-collapsible-collapsed by default unless options to set them false are added.
ui-collapsible-heading: Always visible part of collapsible, which is clicked to open it. Additionally contains ui-collapsible-heading-collapsed class when the collapsible is closed.
ui-collapsible-heading-toggle: Toggler for collapsible
ui-collapsible-heading-status: Status text of the toggler
ui-collapsible-content: Content of the collapsible. Additionally contains ui-collapsible-content-collapsed class in case the content is collapsed.
When you add the data-collapsed="false" attribute to the wrapper the collapsible will initially be expanded.
<div data-role="collapsible" data-collapsed="false">
This code will create a collapsible widget like this:
By default collapsibles have an inset appearance. To make them full width without corner styling add the data-inset="false" attribute to the element.
<div data-role="collapsible" data-inset="false">
This code will create a non-inset collapsible:
For a more compact version that is useful in toolbars and tight spaces, add the data-mini="true" attribute to the element to create a mini version.
<div data-role="collapsible" data-mini="true">
This code will create a mini collapsible widget:
The default icon of collapsible headings can be overridden by using the data-collapsed-icon and data-expanded-icon attributes. The example below uses data-collapsed-icon="arrow-r" and data-expanded-icon="arrow-d".
The default icon positioning of collapsible headings can be overridden by using the data-iconpos attribute. The example below uses data-iconpos="right".
Collapsible content is minimally styled - we add only a bit of margin between the bar and content, and the header adopts the default theme styles of the container within which it sits.
To provide a stronger visual connection between the collapsible header and content, add the data-content-theme attribute to the wrapper and specify a theme swatch letter. This applies the border and background color of the swatch to the content block and changes the corner rounding to square off the bottom of the header and round the bottom of the content block instead to visually group these elements.
<div data-role="collapsible" data-content-theme="b">
<h3>Header</h3>
<p>I'm the collapsible content with a themed content block set to "b".</p>
</div>
To set the theme on a collapsible header button, add the data-theme attribute to the wrapper and specify a swatch letter. Note that you can mix and match swatch letters between the header and content with these theme attributes.
<div data-role="collapsible" data-theme="b" data-content-theme="b">
<h3>Header swatch B</h3>
<p>I'm the collapsible content with a themed content block set to "b".</p>
</div>
Collapsibles can be nested inside each other if needed. In this example, we're setting the content theme to provide clearer visual connection between the levels.
It's possible to combine multiple collapsibles into a grouped set that acts like an accordion widget.
You can improve the load time of your page by providing the markup that the collapsible widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the collapsible widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The collapsible widget creates an anchor from the heading element and wraps the rest of the children of the outermost widget in a div that will serve as the container for the collapsible content.
In the example below, pre-rendered markup for a collapsible is provided. The attribute data-collapsed-icon="arrow-r" is explicitly specified, since the use of theui-icon-arrow-r class on the anchor element indicates that the value of the "collapsedIcon" widget option is to be "arrow-r".
<div data-role="collapsible" data-enhanced="true" class="ui-collapsible ui-collapsible-inset ui-corner-all ui-collapsible-collapsed" data-collapsed-icon="arrow-r">
<h2 class="ui-collapsible-heading ui-collapsible-heading-collapsed">
<a href="#" class="ui-collapsible-heading-toggle ui-btn ui-btn-icon-left ui-icon-arrow-r">
Pre-rendered collapsible
<span class="ui-collapsible-heading-status"> click to expand contents</span>
</a>
</h2>
<div class="ui-collapsible-content ui-collapsible-content-collapsed" aria-hidden="true">
<p>This is the collapsible-content</p>
</div>
</div>
optionName.optionName.jQuery Mobile will visually style a set of collapsibles as a group and will make the set behave like an accordion in that only one collapsible can be open at a time if you wrap the collapsibles in a div that has the attribute data-role="collapsibleset".
By default, all the collapsible sections will be collapsed. To set a section to be open when the page loads, add the data-collapsed="false" attribute to the heading of the section you want expanded.
<div data-role="collapsible-set">
<div data-role="collapsible" data-collapsed="false">
<h3>Section 1</h3>
<p>I'm the collapsibleset content for section 1. My content is initially visible.</p>
</div>
<div data-role="collapsible">
<h3>Section 2</h3>
<p>I'm the collapsibleset content for section 2.</p>
</div>
</div>
Here is an example of a collapsibleset widget with 5 sections.
For full width collapsibles without corner styling add the data-inset="false" attribute to the set.
For a more compact version that is useful in tight spaces, add the data-mini="true" attribute to the set to create a mini version.
The icon displayed when a collapsible is shown or hidden can be overridden by using the data-collapsed-icon and data-expanded-icon attributes. Both the collapsibleset widget and the collapsible widget accepts these attributes. When you set one or both of these attributes on the collapsibleset widget all collapsible widgets that are part of the collapsibleset display the icon specified by the chosen value. You can override the icon displayed by individual collapsible widgets by setting one or both of these attributes on the collapsible widget itself.
The default icon positioning for collapsible headings can be overridden by using the data-iconpos attribute. You can set the attribute either on the collapsibleset to affect all collapsibles in the set, or on an individual collapsible widget to affect only the one widget.
The standard data-theme attribute can be used to set the color of each collapsible in a set. To provide a clearer visual grouping of the content with the headers, add the data-content-theme attribute with a swatch letter. This adds a themed background color and border to the content block. For consistent theming, add these attributes to the parent collapsibleset widget.
<div data-role="collapsible-set" data-theme="b" data-content-theme="a">
To have individual sections in a group styled differently, add data-theme and data-content-theme attributes to specific collapsibles.
You can improve the load time of your page by providing the markup that the collapsibleset widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the collapsibleset widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The collapsibleset widget does not require that the collapsibles it contains also be pre-rendered.
In the example below, pre-rendered markup for a collapsibleset is provided. The attribute data-corners="false" is explicitly specified, since the absence of the ui-corner-all class on the container element indicates that the "corners" widget option is to be false. One of the child collapsibles is provided as-is, while the other is pre-rendered.
<div data-role="collapsibleset" class="ui-collapsible-set" data-corners="false">
<div data-role="collapsible">
<h2>Child collapsible</h2>
<p>This is the collapsible content.</p>
</div>
<div data-role="collapsible" data-enhanced="true" class="ui-collapsible ui-collapsible-inset ui-corner-all" data-collapsed="false" data-corners="true">
<h2 class="ui-collapsible-heading">
<a href="#" class="ui-collapsible-heading-toggle ui-btn ui-btn-icon-left ui-icon-minus">
Pre-rendered child collapsible
<span class="ui-collapsible-heading-status">click to collapse contents</span>
</a>
</h2>
<div class="ui-collapsible-content" aria-hidden="false">
<p>This is the collapsible content.</p>
</div>
</div>
</div>
optionName.optionName.If you manipulate a collapsibleset widget via JavaScript (e.g. by adding new collapsibles, removing old ones, or showing/hiding existing ones), you must call the refresh method on it to update the visual styling. This method will instantiate collapsibles on child elements which are marked data-role="collapsible", so there is no need to manually call .collapsible().
The jQuery UI controlgroup widget is bundled in jQuery Mobile with some changes. Thus, its API documentation fully describes its functionality.
Note: controlgroup method is deprecated in 1.5 and will be removed in 1.6
$( ".selector" ).controlgroup( "container" );
dialog option provided by the page.dialog extension of the page widget allows you to style a page as a dialog, however, the special navigational handling will be removed. You may also consider implementing dialogs using popup widgets.Any page can be presented as a modal dialog by adding the data-rel="dialog" attribute to the page anchor link. When the "dialog" attribute is applied, the framework adds styles to add rounded corners, margins around the page and a dark background to make the "dialog" appear to be suspended above the page.
<a href="foo.html" data-rel="dialog">Open dialog</a>
You can open a dialog programmatically by calling the $.mobile.changePage method:
// Dialog loaded via Ajax
$.mobile.changePage( "path/to/dialog.html", { role: "dialog" } );
// Dialog present in a multipage document
$.mobile.changePage( "#myDialog", { role: "dialog" } );
By default, the dialog will open with a 'pop' transition. Like all pages, you can specify any page transition you want on the dialog by adding the data-transition attribute to the link. To make it feel more dialog-like, we recommend specifying a transition of "pop", "slidedown" or "flip".
Possible values include: fade, pop, flip, turn, flow, slidefade, slide, slideup, slidedown, none.
<a href="foo.html" data-rel="dialog" data-transition="pop">Open dialog</a>
When any link is clicked within a dialog, the framework will automatically close the dialog and transition to the requested page, just as if the dialog were a normal page. Nevertheless, dialogs can also be chained, as explained below under "Chaining Dialogs". Similarly, a link that opens a popup will also leave the dialog in place.
If the dialog has a header the framework will add a close button at the left side of the header. You can change the position by adding data-close-btn="right" to the dialog container. If you don't want a close button in the header or add a custom close button, you can use data-close-btn="none".
To create a "cancel" button in a dialog, just link to the page that triggered the dialog to open and add the data-rel="back" attribute to your link. This pattern of linking to the previous page is also usable in non-JS devices as well.
For JavaScript-generated links, you can simply set the href attribute to "#" and use the data-rel="back" attribute. You can also call the dialog's close() method to programmatically close dialogs, for example: $( ".ui-dialog" ).dialog( "close" ).
Just like the page plugin, you can set a dialog's close button text through an option or data attribute. The option can be configured for all dialogs by binding to the mobileinit event and setting the $.mobile.dialog.prototype.options.closeBtnText property to a string of your choosing, or you can place the data attribute data-close-btn-text to configure the text from your markup.
Since dialogs are typically used to support actions within a page, the framework does not include dialogs in the hash state history tracking. This means that dialogs will not appear in your browsing history chronology when the Back button is clicked. For example, if you are on a page, click a link to open a dialog, close the dialog, then navigate to another page, if you were to click the browser's Back button at that point you will navigate back to the first page, not the dialog.
Please note: If a dialog opens another dialog (chaining), closing the last one with a link of type data-rel="back" will always navigate to the previous dialog until the root-page of type data-role="page" is reached. This guarantees a consistent navigation between dialogs.
Dialogs can be styled with different theme swatches, just like any page by adding data-theme attributes to the header, content, or footer containers.
By default dialogs have rounded corners. The option corners can be set to false by adding data-corners="false" to the dialog container:
Dialogs appear to be floating above an overlay layer. This overlay adopts the swatch 'a' content color by default, but the data-overlay-theme attribute can be added to the page wrapper to set the overlay to any swatch letter.
Dialogs can also be used more like a control sheet to offer multiple buttons if you simply remove the top margin from the dialog's inner container element. For example, if your dialog page had a class of my-dialog, you could add this CSS to pin that dialog to the top: .ui-dialog.my-dialog .ui-dialog-contain { margin-top: 0 }, or you could just apply that style to all dialogs with .ui-dialog .ui-dialog-contain { margin-top: 0 }.
For the sake of readability, dialogs have a default width of 92.5% and a max-width of 500 pixels. There is also a 10% top margin to give dialogs larger top margin on larger screens, but collapse to a small margin on smartphones. The dialog's inner container is shifted towards the top with 15px to hide the corner styling if a dialog is used as a control sheet (see above). To override these styles, add the following CSS override rule to your stylesheet and tweak as needed:
.ui-dialog-contain {
width: 92.5%;
max-width: 500px;
margin: 10% auto 15px auto;
padding: 0;
position: relative;
top: -15px;
}
data-rel="dialog" to the anchor tag.This method is responsible for performing all jQuery Mobile enhancement. Given a set of DOM elements it will enhance their children with all the widgets available.
The enhancement is based on each widget's initSelector property. This selector will be used to identify the elements upon which the widget will be instantiated.
You can shield elements and their children from enhancement by adding the attribute data-enhance="false" to an element. This will cause it, and all its children to be ignored by .enhanceWithin(). Unfortunately, checking elements to see whether they are children of an element that has been marked with data-enhance="false" is performance-intensive. Thus, the presence of data-enhance="false" will only be considered if the global flag $.mobile.ignoreContentEnabled is set to true.
Caveat: enhanceWithin does not attempt to resolve issues related to the order in which widgets are enhanced. For example, enhancing filterable widgets before checkboxradio widgets are enhanced can cause the checkboxradio widgets to be displayed incorrectly. If this affects you, then you must ensure that the widgets which need to be enhanced early are instantiated before the rest of the widgets. One possibility for accomplishing this is to instantiate your widgets during the page widget's pagebeforecreate event.
enhanceWithin.The filterable widget allows you to filter the children of an element. The filtering is accomplished by applying the class ui-screen-hidden to those children for which a filter callback function provided via the widget's filterCallback option returns true.
The filterable widget is a generalization of the listview widget's filter extension that was available in jQuery Mobile 1.3. It retains API compatibility with the listview filter. Its behavior is also made backwards compatible by the following deprecated features:
data-input attribute, it will generate a text input and place it before the element.filterPlaceholder option which sets the placeholder attribute on the generated text input.filterTheme option which sets the theme option on the generated text input.hidedividers option, which causes the new listview hidedividers extension to automatically hide dividers for categories wherein all items are hidden.To render the children of an element filterable, perform the following steps:
change signal and has a value that can be accessed via the jQuery .val() plugin. This is usually a text input. The filterable widget reacts to the change signal by reading the value of the input after a short delay and iterating over all the children to determine whether they should be shown or hidden according to the filter callback provided.data-filter="true" to the element whose children will be filtered.data-input to the element whose children will be filtered. The value of the attribute is a string containing a jQuery selector that will return the element to be used as the source for the filterable.refresh method on the filterable widget, to ensure that the new children are shown or hidden in accordance with the latest input provided by the user.
Child elements may have the data-filtertext attribute set. In that case, the default filter callback will hide a given child element only if the value of the data-filtertext attribute does not contain the string provided by the user. If the data-filtertext attribute is absent, the child will be hidden if its text content does not contain the string provided by the user.
<form>
<input type="text" data-type="search" id="filterable-input">
</form>
<form data-role="controlgroup" data-filter="true" data-input="#filterable-input">
<label for="pizza">
Pizza
<input type="checkbox" id="pizza">
</label>
<label for="goulash">
Goulash
<input type="checkbox" id="goulash">
</label>
<label for="falafel">
Falafel
<input type="checkbox" id="falafel">
</label>
<label for="spring-rolls">
Spring Rolls
<input type="checkbox" id="spring-rolls">
</label>
</form>
The normal initial state of a filterable widget is that all the children are shown. In contrast, a filterable in "reveal" mode initially hides all its children. Once the user starts filtering, however, the filterable widget will display only those children that contain the text entered by the user, whether the filterable widget is in "reveal" mode or not.
You can turn on "reveal" mode by adding the attribute data-filter-reveal="true" to the element whose children will be filtered.
The example below illustrates the behavior of a filterable widget in "reveal" mode:
<form>
<input type="text" data-type="search" id="filterable-input">
</form>
<form data-role="controlgroup" data-filter-reveal="true" data-filter="true" data-input="#filterable-input">
<label for="pizza">
Pizza
<input type="checkbox" id="pizza">
</label>
<label for="goulash">
Goulash
<input type="checkbox" id="goulash">
</label>
<label for="falafel">
Falafel
<input type="checkbox" id="falafel">
</label>
<label for="spring-rolls">
Spring Rolls
<input type="checkbox" id="spring-rolls">
</label>
</form>
The filterable widget's filterCallback option allows you to set a custom callback. In the example below items are filtered by their ordinal, which can be specified using page printing conventions such as "1,2" or "4-9", or both ("1,2,4-9,12").
$.mobile.filterable.prototype.options.filterCallback = function( index, searchValue ) {
var idx;
if ( searchValue ) {
searchValue = searchValue.split( "," );
searchValue = $.map( searchValue, function( element ) {
var ar = element.split( "-" );
return ar.length === 1 ? parseInt( element ) :
[ [ parseInt( ar[ 0 ] ), parseInt( ar[ 1 ] ) ] ];
});
for ( idx = 0 ; idx < searchValue.length ; idx++ ) {
if ( ( $.type( searchValue[ idx ] ) === "number" &&
index === searchValue[ idx ] ) ||
( $.type( searchValue[ idx ] ) === "array" &&
index >= searchValue[ idx ][ 0 ] &&
index <= searchValue[ idx ][ 1 ] ) ) {
return false;
}
}
}
return !!searchValue;
};
You can improve the load time of your page by providing the markup that the filterable widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the filterable widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The filterable widget runs the filter on its children upon instantiation to ensure that the initial list of displayed children satisfies the initial value of the input source. By setting the attribute data-enhanced="true", you instruct the filterable widget that no initial filtering is to be performed. This means that you must apply the class ui-screen-hidden to any children which must initially be hidden due to the initial value of the search input.
Note: If the element whose children are to be filtered is enhanced by another widget as well, such as for example a listview or a controlgroup then you are required to provide pre-rendered markup for the other widget as well, because the attribute data-enhanced="true" will influence the initialization behavior of the other widget as well.
In the example below, pre-rendered markup for a filterable is provided. The attribute data-filter-reveal="true" is explicitly specified, since the presence of the ui-screen-hidden class on all the children indicates that they are initially hidden. The controlgroup widget containing the children is also pre-rendered, because the data-enhanced="true" attribute applies to the controlgroup widget as much as it does to the filterable widget.
<form>
<input id="pre-rendered-filterable" data-type="search">
</form>
<div
class="ui-controlgroup ui-controlgroup-vertical ui-corner-all"
data-role="controlgroup"
data-filter="true"
data-input="#pre-rendered-filterable"
data-filter-reveal="true"
data-enhanced="true">
<div class="ui-controlgroup-controls">
<a href="index.html" class="ui-screen-hidden" data-role="button">General</a>
<a href="settings.html" class="ui-screen-hidden" data-role="button">Settings</a>
<a href="advanced.html" class="ui-screen-hidden" data-role="button">Advanced</a>
<a href="notifications.html" class="ui-screen-hidden" data-role="button">Notifications</a>
</div>
</div>
ui parameter contains the list of children that was processed.optionName.optionName.If you manipulate a filterable widget via JavaScript (e.g. by adding new children or removing old ones), you must call the refresh() method on it to update the visual styling.
As of jQuery Mobile 1.4.0 the functionality of the fixedtoolbar widget has been moved to the toolbar widget.
The flip switch is an alternative look to the checkbox or the two-option select menu. It can be toggled by a click or a swipe.
To create a flip switch add the attribute data-role="flipswitch" to a checkbox input or to a select which has two option values.
The flipswitch widget uses the jQuery Mobile CSS framework to style its look and feel. If flipswitch specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-flipswitch: The outermost container for flipswitch. Additionally, ui-flipswitch-active class will be applied in case flipswitch is in active
ui-flipswitch-on: On state label of flipswitch
ui-flipswitch-off: Off state label of flipswitch
ui-flipswitch-input: Input checkbox element for flipswitch
Use the following markup to create a flipswitch based on a checkbox input:
<fieldset>
<div data-role="fieldcontain">
<label for="checkbox-based-flipswitch">Checkbox-based:</label>
<input type="checkbox" id="checkbox-based-flipswitch" data-role="flipswitch">
</div>
</fieldset>
The labels for the flipswitch are controlled by the onText and offText options.
You can also create a flipswitch based on a select element:
<fieldset>
<div data-role="fieldcontain">
<label for="select-based-flipswitch">Select-based:</label>
<select id="select-based-flipswitch" data-role="flipswitch">
<option value="leave">Bye</option>
<option value="arrive">Hi</option>
</select>
</div>
</fieldset>
The labels for the flipswitch are controlled by the labels of the select element's option elements. The first option is used for the inactive, "off" state, and the second option is used for the active, "on" state.
You can customize the labels displayed by the flipswitch widget either using the onText and offText options if the widget is based on a checkbox, or using the text inside the first two option elements if the widget is based on a select.
The location of the text inside the two labels is specified manually in the flipswitch widget's structural CSS. Thus, if you use labels that are longer than "On" and "Off", you may have to override the default text placement using the following custom CSS:
.ui-flipswitch .ui-btn.ui-flipswitch-on {
text-indent: -2.6em;
}
.ui-flipswitch .ui-flipswitch-off {
text-indent: 1em;
}
Depending on your choice of labels, you may also have to provide custom CSS to override the default width for the flipswitch:
.ui-flipswitch {
width: 5.875em;
}
.ui-flipswitch.ui-flipswitch-active {
padding-left: 4em;
width: 1.875em;
}
@media (min-width: 28em) {
// Repeated from rule .ui-flipswitch above
.ui-field-contain > label + .ui-flipswitch {
width: 1.875em;
}
}
You can improve the load time of your page by providing the markup that the flipswitch widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the flipswitch widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The flipswitch widget adds a wrapper div around the input. In addition to the original element, the wrapper also contains two span elements where the two labels are stored. The first span is styled as a button with the text for the active state appearing outside the button's bounding box to the left. To make the flipswitch reachable by tabbing, you can add the tabindex="1" attribute to the first span.
In the example below, pre-rendered markup for a flipswitch is provided. The attribute data-corners="false" is explicitly specified, since the absence of the ui-corner-all class on the wrapper element indicates that the "corners" widget option is to be false.
<div class="ui-flipswitch ui-shadow-inset ui-bar-inherit">
<span tabindex="1" class="ui-flipswitch-on ui-btn ui-shadow ui-btn-inherit">On</span>
<span class="ui-flipswitch-off">Off</span>
<input type="checkbox" data-role="flipswitch" data-enhanced="true" data-corners="false" name="flip-checkbox" class="ui-flipswitch-input">
</div>
optionName.optionName.If you manipulate a flipswitch via JavaScript, you must call the refresh method on it to update the visual styling.
As of jQuery Mobile 1.4.0 the functionality of the footer widget has been moved to the toolbar widget.
Using multiple column layouts isn't generally recommended on a mobile device because of the narrow screen width, but there are times where you may need to place small elements side-by-side (like buttons or navigation tabs, for example).
The jQuery Mobile framework provides a simple way to build CSS-based columns through a block style class convention called ui-grid.
There are four preset layouts that can be used in any situation that requires columns:
ui-grid-a class)ui-grid-b class)ui-grid-c class)ui-grid-d class)Grids are 100% width, completely invisible (no borders or backgrounds) and don't have padding or margins, so they shouldn't interfere with the styles of elements placed inside them.
Within the grid container, child elements are assigned ui-block-a/b/c/d/e in a sequential manner which makes each "block" element float side-by-side, forming the grid. The ui-block-a class essentially clears the floats which will start a new line (see multiple row grids, below).
To build a two-column (50/50%) layout, start with a container with a class of ui-grid-a, and add two child containers inside it classed with ui-block-a for the first column and ui-block-b for the second:
<div class="ui-grid-a">
<div class="ui-block-a"><strong>I'm Block A</strong> and text inside will wrap</div>
<div class="ui-block-b"><strong>I'm Block B</strong> and text inside will wrap</div>
</div><!-- /grid-a -->
The above markup produces the following content layout:
As you see above, by default grid blocks have no visual styling; they simply present content side-by-side.
Grid classes can be applied to any container. In this next example, we add ui-grid-a to a fieldset, and apply the ui-block classes to the container of each of the two buttons inside to stretch them each to 50% of the screen width:
<fieldset class="ui-grid-a">
<div class="ui-block-a"><button type="submit" data-theme="a">Cancel</button></div>
<div class="ui-block-b"><button type="submit" data-theme="b">Submit</button></div>
</fieldset>
Please note that the framework adds left and right margin to buttons in a grid. For a single button you can use a container with class ui-grid-solo and wrap the button in a div with class ui-block-a like the example below. This way the button will get the same margin.
<div class="ui-grid-a">
<div class="ui-block-a"><button type="button" data-theme="a">Previous</button></div>
<div class="ui-block-b"><button type="button" data-theme="a">Next</button></div>
</div>
<div class="ui-grid-solo">
<div class="ui-block-a"><button type="button" data-theme="b">More</button></div>
</div>
Theme classes (not data-theme attributes) from the theming system can be added to an element, including grids. On the blocks below, we're adding two classes: ui-bar to add the default bar padding and ui-bar-a to apply the background and font styling for the "a" toolbar theme swatch. For illustration purposes, an inline style="height:120px" attribute is also added to each grid to set each to a standard height.
The other grid layout configuration uses class=ui-grid-b on the parent, and 3 child container elements, each with its respective ui-block-a/b/c class, to create a three-column layout (33/33/33%). Note: These blocks are also styled with theme classes so the grid layout is clearly visible.
<div class="ui-grid-b">
<div class="ui-block-a">Block A</div>
<div class="ui-block-b">Block B</div>
<div class="ui-block-c">Block C</div>
</div><!-- /grid-b -->
This will produce a 33/33/33% grid for our content.
And an example of a 3 column grid with buttons inside:
A four-column, 25/25/25/25% grid is created by specifying class=ui-grid-c on the parent and adding a fourth block. Note: These blocks are also styled with theme classes so the grid layout is clearly visible.
A five-column, 20/20/20/20/20% grid is created by specifying class=ui-grid-d on the parent and adding a fifth block. Note: These blocks are also styled with theme classes so the grid layout is clearly visible.
Grids are designed to wrap to multiple rows of items. For example, if you specify a 3-column grid (ui-grid-b) on a container that has nine child blocks, it will wrap to 3 rows of 3 items each. There is a CSS rule to clear the floats and start a new line when the class=ui-block-a is seen so make sure to assign block classes in a repeating sequence (a, b, c, a, b, c, etc.) that maps to the grid type:
Grids are helpful for creating layouts within a toolbar. Here's a footer with a 4 column grid.
As of jQuery Mobile 1.4.0 the functionality of the header widget has been moved to the toolbar widget.
When working with jQuery Mobile, jqmData should be used in place of jQuery core's data method (note that this includes $.fn.data, $.fn.removeData, and the $.data, $.removeData, and $.hasData utilities), as they automatically incorporate getting and setting of namespaced data attributes (even if no namespace is currently in use).
Note: jqmData is deprecated as of version 1.5 and will be removed in version 1.6.
jqmData() with no argument will return undefined. This behavior is subject to change in future versions.When finding elements by their jQuery Mobile data attribute, please use the custom selector :jqmData(). It automatically incorporates namespaced data attributes into the lookup when they are in use. For example, instead of calling $("div[data-role='page']"), you should use $("div:jqmData(role='page')"), which internally maps to $("div[data-"+ $.mobile.ns +"role='page']") without forcing you to concatenate a namespace into your selectors manually.
One exception to this rule is selecting on namespaced data attributes with URL values, e.g the :jqmData(url) that jQuery Mobile uses to track where a page came from. This is because the selector requires a closing parentheses but the parentheses is also valid URL character.
Some native input types have undesirable native behavior. jQuery.mobile.degradeInputsWithin will alter the input type of such elements during page creation to fallback input types whose native behavior is acceptable. You can then achieve the user experience you desire by instantiating jQuery Mobile widgets on the modified native elements.
Note: jQuery.mobile.getDocumentBase is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Use the jQuery.mobile.path.getDocumentBase() method instead.
The $.mobile.navigate method provides a uniform history manipulation API for browsers that support the new history API and those that don't (hashchange). It works in concert with the navigate event by storing and retrieving arbitrary data in association with a URL (much like popState and replaceState). When the user returns to a URL set by the navigate method the navigate event is triggered with the associated data.
Note: This method is a low-level utility which can be used on its own. If you use the jQuery Mobile navigation framework, you should not separately use this utility. Instead, you should use pagecontainer methods to navigate to another page.
// Starting at http://example.com/
// Alter the URL: http://example.com/ => http://example.com/#foo
$.mobile.navigate( "#foo", { info: "info about the #foo hash" });
// Alter the URL: http://example.com/#foo => http://example.com/#bar
$.mobile.navigate( "#bar" );
// Bind to the navigate event
$( window ).on( "navigate", function( event, data ) {
console.log( data.state.info );
console.log( data.state.direction )
console.log( data.state.url )
console.log( data.state.hash )
});
// Alter the URL: http://example.com/#bar => http://example.com/#foo
window.history.back();
// From the `navigate` binding on the window, console output:
// => "info about the #foo hash"
// => "back"
// => "http://example.com/#bar
// => "#bar"
// Starting at http://example.com/
// Define a click binding for all anchors in the page
$( "a" ).on( "click", function( event ) {
// Prevent the usual navigation behavior
event.preventDefault();
// Alter the url according to the anchor's href attribute, and
// store the data-foo attribute information with the url
$.mobile.navigate( this.attr( "href" ), { foo: this.attr( "data-foo" ) });
// Hypothetical content alteration based on the url. E.g, make
// an ajax request for JSON data and render a template into the page.
alterContent( this.attr( "href" ) );
});
$(document).ready(function() {
$( ".myButton" ).on( "click", function() {
var dirName = $.mobile.path.get( $( this ).attr( "value" ) );
$( "#myResult" ).html( String( dirName ) );
})
});
Utility method for determining the directory portion of an URL. If the URL has no trailing slash, the last component of the URL is considered to be a file. This function returns the directory portion of a given URL.
The browser's location.href may contain the username/password information. getLocation() always returns location.href stripped of the username/password information if present, ensuring that your code is not vulnerable to XSS attacks.
$(document).ready(function() {
$( ".myButton" ).on( "click", function() {
var isAbs = $.mobile.path.isAbsoluteUrl( $( this ).attr( "value" ) );
$( "#myResult" ).html( String( isAbs ) );
})
});
Utility method for determining if a URL is absolute. This function returns a boolean true if the URL is absolute, false if not.
$(document).ready(function() {
$( ".myButton" ).on( "click", function() {
var isRel = $.mobile.path.isRelativeUrl( $( this ).attr( "value" ) );
$( "#myResult" ).html( String( isRel ) );
})
});
Utility method for determining if a URL is relative variant. This function returns a boolean true if the URL is relative, false if it is absolute.
$(document).ready(function() {
$( ".compare" ).on( "click", function() {
var urlContainers = $( this ).siblings( ".versus" ).find( "code" ),
url1 = urlContainers.first().text(),
url2 = urlContainers.last().text();
$( "#myResult" ).text( String( $.mobile.path.isSameDomain( url1, url2 ) ) );
})
});
Utility method for determining if two different URLs share the same domain. This function returns a boolean true if the domain is the same, false if not.
$(document).ready(function() {
$( ".myButton" ).on( "click", function() {
var arguments = $( this ).attr( "value" ).split( " relative to " ),
absolutePath = $.mobile.path.makePathAbsolute( arguments[ 0 ], arguments[ 1 ] );
$( "#myResult" ).text( absolutePath );
})
});
Given a path that is relative to another absolute path, this utility will convert the relative path to an absolute path based on the given absolute path.
$(document).ready(function() {
$( ".myButton" ).on( "click", function() {
var absUrl = $.mobile.path.makeUrlAbsolute( $( this ).attr( "value" ), "http://foo.com/a/b/c/test.html" );
$( "#myResult" ).html( absUrl );
})
});
This function returns a string that is an absolute version of the relative URL passed in.
This method gets the current location via getLocation() and returns the result of parsing this value via parseUrl().
$(document).ready(function() {
$( ".myButton" ).on( "click", function() {
// Parsing the Url below results an object that is returned with the
// following properties:
//
// obj.href: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content
// obj.hrefNoHash: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread
// obj.hrefNoSearch: http://jblas:password@mycompany.com:8080/mail/inbox
// obj.domain: http://jblas:password@mycompany.com:8080
// obj.protocol: http:
// obj.authority: jblas:password@mycompany.com:8080
// obj.username: jblas
// obj.password: password
// obj.host: mycompany.com:8080
// obj.hostname: mycompany.com
// obj.port: 8080
// obj.pathname: /mail/inbox
// obj.directory: /mail/
// obj.filename: inbox
// obj.search: ?msg=1234&type=unread
// obj.hash: #msg-content</strong>
var obj = $.mobile.path.parseUrl("http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content");
var myChoice = eval( this.value );
$( "#myResult" ).html( myChoice );
})
});
Utility method for parsing a URL and its relative variants into an object that makes accessing the components of the URL easy. When parsing relative variants, the resulting object will contain empty string values for missing components (like protocol, host, etc). Also, when parsing URLs that have no authority, such as tel: urls, the pathname property of the object will contain the data after the protocol/scheme colon.
This function returns an object that contains the various components of the URL as strings. The properties on the object mimic the browser's location object:
hashhosthostnamehrefpathnameportprotocolsearchBut it also contains additional properties that provide access to additional components as well as some common forms of the URL developers access:
authoritydirectorydomainfilenamehrefNoHashhrefNoSearchpasswordusernameScroll to a particular Y position without triggering scroll event listeners.
A listview is coded as a simple unordered list containing linked list items with a data-role="listview" attribute. jQuery Mobile will apply all the necessary styles to transform the list into a mobile-friendly listview with right arrow indicator that fills the full width of the browser window. When you tap on the list item, the framework will trigger a click on the first link inside the list item, issue an Ajax request for the URL in the link, create the new page in the DOM, then kick off a page transition. View the data- attribute reference to see all the possible attributes you can add to listviews.
Here is the HTML markup for a basic linked list.
<ul data-role="listview">
<li><a href="acura.html">Acura</a></li>
<li><a href="audi.html">Audi</a></li>
<li><a href="bmw.html">BMW</a></li>
</ul>
The listview widget uses the jQuery Mobile CSS framework to style its look and feel. If listview specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-listview: Outermost container for listview widget
ui-listview-item-static: Simplest list item of listview when there are no anchor tags nested inside an item
ui-listview-item-divider: List item element which is a divider
ui-listview-item-has-alternate: List item element which has more than one anchor elements
ui-listview-item-button: First anchor element
ui-listview-item-split-button: Last anchor element
ui-listview-item-split-icon: Icon of last anchor element
ui-listview-item: List item element which has only one anchor elements. If the listview item has count bubble, it will additionally have ui-listview-item-has-count class.
ui-listview-item-button: Anchor element of the list item
ui-listview-item-icon: Icon for the list item
ui-listview-item-count-bubble: Count bubble for list item if present
Style note on non-inset lists: all standard, non-inset lists have a -1em (16px) margin to negate the 1em padding on the content area to make lists extend to the edges of the screen. If you add other widgets above or below a list, the negative margin may make these elements overlap so you'll need to add additional spacing in your custom CSS.
Lists can also be created from ordered lists (ol) which is useful when presenting items that are in a sequence such as search results or a movie queue. When the enhanced markup is applied to the listview, jQuery Mobile will try to first use CSS to add numbers to the list and, if not supported, will fall back to injecting numbers with JavaScript.
Listviews can also be used to display a non-interactive list of items, usually as an inset list. This list is built from an unordered or ordered list that don't have linked list items. The framework styles static list items identically to list items containing links, but static items receive the body background color (ui-body-a) rather than the button background color (ui-btn-a).
In cases where there is more than one possible action per list item, a split button can be used to offer two independently clickable items - the list item and a small arrow icon in the far right. To make a split list item, simply add a second link inside the li and the framework will add a vertical divider line, style the link as an icon-only arrow button, and set the title attribute of the link to the text of the link for accessibility.
You can set the icon for the right split icon by specifying a data-split-icon attribute on the listview with an icon name you want. The default icon is "carat-r" but can be configured with the splitIcon listview option. By adding a data-icon attribute to the list item, you can set individual icons for each split. The theme swatch color of the split button defaults to "b" (blue in the default theme) but can be set by specifying a swatch letter with the data-split-theme attribute at the listview level or for individual splits with the data-theme attribute at the link level.
List items can be turned into dividers to organize and group the list items. This is done by adding the data-role="list-divider" to any list item. These items are styled with the bar swatch "b" by default (blue in the default theme) but you can specify a theme for dividers by adding the data-divider-theme attribute to the list element (ul or ol) and specifying a theme swatch letter.
A listview can be configured to automatically generate dividers for its items. This is done by adding a data-autodividers="true" attribute to any listview.
By default, the text used to create dividers is the uppercased first letter of the item's text. Alternatively you can specify divider text by setting the autodividersSelector option on the listview programmatically. For example, to add a custom selector to the element with id="mylistview":
$( "#mylistview" ).listview({
autodividers: true,
// the selector function is passed a <li> element from the listview;
// it should return the appropriate divider text for that <li>
// element as a string
autodividersSelector: function ( li ) {
var out = /* generate a string based on the content of li */;
return out;
}
});
Note that if you are using formatted list items that contain a floating element (for example ui-li-aside), this element precedes its siblings regardless of the order in your HTML markup. This results in the first character of the floating element being used as divider text. Therefore it is recommended to specify the divider text in this case.
If new list items are added to the list or removed from it, the dividers are not automatically updated: you should call refresh() on the listview to redraw the autodividers.
The listview hidedividers extension provides the option hideDividers. When set to true, and you call .listview( "refresh" ) after hiding a list item by adding the class ui-screen-hidden to it, the extension will hide those dividers that are followed immediately by another divider.
As of jQuery Mobile 1.4.0 this functionality has been transferred to the filterable widget, which provides a more generic solution.
Note: Features such as automatic text input generation and special handling of listview dividers are deprecated as of 1.4.0. The documentation for filterable describes the migration path for listviews.
The filter reveal feature makes is easy to build a simple autocomplete with local data. When a filterable list has the data-filter-reveal="true" attribute, it will auto-hide all the list items when the search field is blank. The data-filter-placeholder attribute can be added to specify the placeholder text for the filter. If you need to search against a long list of values, we provide a way to create a filter with a remote data source.
To use the filter as an autocomplete that taps into remote data sources, you can use the filterablebeforefilter event to dynamically populate a listview as a user types a search query. This is useful when you have a very large data set like cities, zip codes, or products that can't be loaded up-front locally. Use the view source button to see the JavaScript that powers this demo.
If you have a small list of items, you can use the listview filter reveal option to make an autocomplete with local listview data.
After you enter at least three characters the autocomplete function will show all possible matches.
The framework includes text formatting conventions for common list patterns like header/descriptions, secondary information and counts through semantic HTML markup.
ui-li-countui-li-asideTo add thumbnails to the left of a list item, simply add an image inside a list item as the first child element. The framework will scale the image to 80 pixels square. To use standard 16x16 pixel icons in list items, add the class of ui-li-icon to the image element.
If lists are embedded in a page with other types of content, an inset list packages the list into a block that sits inside the content area with a bit of margin and rounded corners (theme controlled). By adding the data-inset="true" attribute to the list (ul or ol), applies the inset appearance.
You can directly call the listview plugin on any selector, just like any jQuery plugin:
$( "#mylist" ).listview();
If you add items to a listview, you'll need to call the refresh() method on it to update the styles. For example:
$( "#mylist" ).listview( "refresh" );
Note that the refresh() method only affects new nodes appended to a list. This is done for performance reasons. Any list items already enhanced will be ignored by the refresh process. This means that if you change the contents or attributes on an already enhanced list item, these won't be reflected. If you want a list item to be updated, replace it with fresh markup before calling refresh.
If you initially want to hide a list item you can do this by adding a class of ui-screen-hidden to the li element. Using this class ensures the corner styling is applied correctly as well as border-bottom on the last visible item.
If you manipulate a listview via JavaScript (e.g. add new LI elements), you must call the refresh method on it to update the visual styling.
The loader widget handles the task of displaying the loading dialog when jQuery Mobile pulls in content via Ajax. It can also be displayed manually for custom loading actions using the $.mobile.loading helper method (See the global method docs).
The loader widget uses the jQuery Mobile CSS framework to style its look and feel. If loader specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-loader: Outermost container for loader widget. If textvisible option is used ui-loader-verbose class will be added. Additionally if textonly option is used then ui-loader-textonly class will added. In all other cases where text is not present ui-loader-default class will be added.
ui-loader-item: Span element of the loader representing the icon
ui-loader-header: Header element of the loader representing the text of the loader.
To configure the loading dialog globally the following settings can be defined on its prototype during the mobileinit event.
$( document ).on( "mobileinit", function() {
$.mobile.loader.prototype.options.text = "loading";
$.mobile.loader.prototype.options.textVisible = false;
$.mobile.loader.prototype.options.theme = "a";
$.mobile.loader.prototype.options.html = "";
});
These defaults will only be superseded by the method params object described in the global method docs under $.mobile.loading.
$.mobile.loading( "show", {
text: "foo",
textVisible: true,
theme: "z",
html: ""
});
$.mobile.loader prototype options as described in the widget docs or can be controlled via a params object.
$(document).on( "click", ".show-page-loading-msg", function() {
var $this = $( this ),
theme = $this.jqmData( "theme" ) || $.mobile.loader.prototype.options.theme,
msgText = $this.jqmData( "msgtext" ) || $.mobile.loader.prototype.options.text,
textVisible = $this.jqmData( "textvisible" ) || $.mobile.loader.prototype.options.textVisible,
textonly = !!$this.jqmData( "textonly" );
html = $this.jqmData( "html" ) || "";
$.mobile.loading( 'show', {
text: msgText,
textVisible: textVisible,
theme: theme,
textonly: textonly,
html: html
});
})
.on( "click", ".hide-page-loading-msg", function() {
$.mobile.loading( "hide" );
});
This event is triggered after jQuery Mobile has finished loading, but before it has started enhancing the start page. Thus, handlers of this event have the opportunity to modify jQuery Mobile's global configuration options and all the widgets' default option values before they influence the library's behavior.
You must connect a handler to the mobileinit event before you load jQuery Mobile, because it is triggered as part of the library's loading process. The easiest way of achieving this is to place a script tag after the script tag that loads jQuery, and before the script tag that loads jQuery Mobile:
<!doctype html>
<html>
<head>
<title>Example illustrating use of the "mobileinit" event</title>
<meta charset=utf-8 />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="//code.jquery.com/mobile/1.5.0-alpha.1/jquery.mobile-1.5.0-alpha.1.min.css" />
<script src="//code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
// Update configuration to our liking
$( document ).on( "mobileinit", function() {
// We want popups to cover the page behind them with a dark background
$.mobile.popup.prototype.options.overlayTheme = "b";
// Set a namespace for jQuery Mobile data attributes
$.mobile.ns = "jqm-";
});
</script>
<script src="//code.jquery.com/mobile/1.5.0-alpha.1/jquery.mobile-1.5.0-alpha.1.min.js"></script>
</head>
<body>
<div data-jqm-role="page">
<div data-jqm-role="header">
<h2>jQuery Mobile Example</h2>
</div>
<div data-jqm-role="content">
<div id="the-popup" data-jqm-role="popup" data-jqm-position-to="window">
<p>Example popup.</p>
</div>
<a href="#the-popup" data-jqm-rel="popup" class="ui-btn ui-corner-all ui-shadow">Open Popup</a>
</div>
</div>
</body>
</html>
jQuery Mobile has a very basic navbar widget that is useful for providing up to 5 buttons with optional icons in a bar, typically within a header or footer. There is also a persistent navbar variation that works more like a tab bar that stays fixed as you navigate across pages.
A navbar is coded as an unordered list of links wrapped in a container element that has the data-role="navbar" attribute. This is an example of a two-button navbar:
<div data-role="navbar">
<ul>
<li><a href="a.html">One</a></li>
<li><a href="b.html">Two</a></li>
</ul>
</div><!-- /navbar -->
When a link in the navbar is clicked it gets the active (selected) state. The ui-btn-active class is first removed from all anchors in the navbar before it is added to the activated link. If this is a link to another page, the class will be removed again after the transition has completed.
To set an item to the active state upon initialization of the navbar, add class="ui-btn-active" to the corresponding anchor in your markup. Additionaly add a class of ui-state-persist to make the framework restore the active state each time the page is shown while it exists in the DOM. The example below shows a navbar with item "One" set to active:
<div data-role="navbar">
<ul>
<li><a href="a.html" class="ui-btn-active ui-state-persist">One</a></li>
<li><a href="b.html">Two</a></li>
</ul>
</div><!-- /navbar -->
Note that this on applies to navbars that are inside a page. If you use a true persistent toolbar that lives outside the page and want to set current item to the active state, you have to add a script that adds the class="ui-btn-active" class.
The navbar items are set to divide the space evenly so in this case, each button is 1/2 the width of the browser window:
Adding a third item will automatically make each button 1/3 the width of the browser window:
Adding a fourth more item will automatically make each button 1/4 the width of the browser window:
The navbar maxes out with 5 items, each 1/5 the width of the browser window:
If more than 5 items are added, the navbar will simply wrap to multiple lines:
Navbars with 1 item will simply render as 100%.
If you want to add a navbar to the top of the page, you can still have a page title and buttons. Just add the navbar container inside the header block, right after the title and buttons in the source order.
If you want to add a navbar to the bottom of the page so it acts more like a tab bar, simply wrap the navbar in a container with a data-role="footer"
<div data-role="footer">
<div data-role="navbar">
<ul>
<li><a href="#">One</a></li>
<li><a href="#">Two</a></li>
<li><a href="#">Three</a></li>
</ul>
</div><!-- /navbar -->
</div><!-- /footer -->
The navbar widget uses the jQuery Mobile CSS framework to style its look and feel. If navbar specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-navbar: Outermost container for navbar widget
ui-navbar-row: Rows of navbar systems. This represents every navbar row except first
ui-navbar-row-n: (n+1)th row of navbar system except first row
Icons can be added to navbar items by adding the data-icon attribute specifying a standard mobile icon to each anchor. By default, icons are added above the text (data-iconpos="top"). The following examples add icons to a navbar in a footer.
The icon position is set on the navbar container instead of for individual links within for visual consistency. For example, to place the icons below the labels, add the data-iconpos="bottom" attribute to the navbar container.
<div data-role="navbar" data-iconpos="bottom">
This will result in a bottom icon alignment:
The icon position can be set to data-iconpos="left":
Or the icon position can be set to data-iconpos="right":
You can add any of the popular icon libraries like Glyphish to achieve the iOS style tab that has large icons stacked on top of text labels. All that is required is a bit of custom styles to link to the icons and position them in the navbar. Here is an example using Glyphish icons and custom styles (view page source for styles) in our navbar:
Icons by Joseph Wain / glyphish.com. Licensed under the Creative Commons Attribution 3.0 United States License.
Navbars inherit the theme swatch from their parent container, just like buttons. If a navbar is placed in the header or footer toolbar, it will inherit the default toolbar swatch "a" for bars unless you set this in the markup.
Here are a few examples of navbars in various container swatches that automatically inherit their parent's swatch letter. Note that in these examples, instead of using a data-theme attribute, we're manually adding the swatch classes to apply the body swatch (ui-body-a) and the class to add the standard body padding (ui-body), but the inheritance works the same way:
To set the theme color for a navbar item, add the data-theme attribute to the individual links and specify a theme swatch. Note that applying a theme swatch to the navbar container is not supported.
$( "div" ).navbar({
create: function(event, ui) { ... }
});
The navigate event is a wrapper around popstate event. In addition to providing a single event for all browsers it also provides a data object in both cases allowing for the unification of handlers. This feature is used by the $.mobile.navigate method to include directionality and URL information.
// Bind to the navigate event
$( window ).on( "navigate", function( event, data ) {
console.log( data.state );
});
// Trigger a navigate event by pushing state
window.history.pushState( { foo: "bar" }, "Title", "http://example.com/#foo" );
// From the `navigate` binding on the window, console output:
// => {}
// Trigger a navigate event by pushing state
window.history.pushState( {}, "Title", "http://example.com/#bar" );
// From the `navigate` binding on the window, console output:
// => {}
// Trigger a navigate event by moving backward through history
window.history.back();
// From the `navigate` binding on the window, console output:
// => { foo: "bar" }
The jQuery Mobile orientationchange event triggers when a device orientation changes, either by turning the device vertically or horizontally. When bound to this event the callback function has the event object. The event object contains an orientation property equal to either "portrait" or "landscape".
Note that we bind to the browser's resize event when orientationchange is not natively supported or if $.mobile.orientationChangeEnabled is set to false.
The timing of the orientationchange event with relation to the change of the client height and width is different between browsers, though the current implementation will give you the correct value for event.orientation derived from window.orientation. This means that if your bindings are dependent on the height and width values you may want to disable orientationChange altogether with $.mobile.orientationChangeEnabled = false to let the fallback resize code trigger your bindings.
"portrait" and "landscape".
// Bind an event to window.orientationchange that, when the device is turned,
// gets the orientation and displays it to on screen.
$( window ).on( "orientationchange", function( event ) {
$( "#orientation" ).text( "This device is in " + event.orientation + " mode!" );
});
// You can also manually force this event to fire.
$( window ).orientationchange();
<h1 id="orientation">orientationchange Not Supported on this Device.</h1>
The page widget is responsible for managing a single item in jQuery Mobile's page-based architecture. It is designed to support either single page widgets within a HTML document, or multiple local internal linked page widgets within a HTML document.
The goal of this model is to allow developers to create websites using best practices — where ordinary links will "just work" without any special configuration — while creating a rich, native-like experience that can't be achieved with standard HTTP requests.
The page widget will auto-enhance its content upon creation. This means that it will instantiate widgets on its child elements by invoking .enhanceWithin() on itself.
The page widget has the option dialog which you can set to true to obtain a page styled like a dialog, such as in the example below:
<div data-role="page" data-dialog="true">
<div data-role="header">
<h2>Are you sure?</h2>
</div>
<div class="ui-content" role="main">
<h2>Are you sure you wish to exit the application?</h2>
<p>You have unsaved changes. If you exit without saving them, you will lose them.</p>
<div class="ui-grid-a">
<div class="ui-block-a">
<a href="#" id="exit-button" class="ui-btn ui-btn-b ui-shadow ui-corner-all">Exit</a>
</div>
<div class="ui-block-b">
<a href="#" id="cancel-button" class="ui-btn ui-shadow ui-corner-all">Cancel</a>
</div>
</div>
</div>
</div>
You can programmatically close a page styled as a dialog by navigating to another page. For example, you can use the pagecontainer change method:
$( ":mobile-pagecontainer" ).pagecontainer( "change", "somepage.html" );
You can also simply go back:
$.mobile.back();
Triggered before a page is created. If one of the handlers returns false, the page is not created.
Triggered after a page has been created and enhancements to the page have been made.
Pages have both data-external-page="true" and data-dom-cache="false" when you call bindRemove(), otherwise the method will do nothing.
Note:This method is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. The new keepNative option replaces it.
Returns the selector used to filter elements which are not to be enhanced.
Note:This method is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0.
Removes the background swatch from the page widget's container (usually the body).
Note:This method is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0.
Sets a new background swatch for the page widget's container (usually the body).
When received with data.toPage set to a string, the event indicates that navigation is about to commence. The value stored in data.toPage is the URL of the page that will be loaded.
When received with data.toPage set to a jQuery object, the event indicates that the destination page has been loaded and navigation will continue.
If the page change cycle was initiated programmatically, and, instead of a URL a jQuery object containing a page was given, then the event will be triggered both times with data.toPage set to the jQuery object containing the destination page.
The pagebeforechange event is triggered either by explicit navigation on the part of the user (e.g. by clicking on a link or by running code that results in a call to the pagecontainer change() method), or by implicit navigation caused by the user clicking the browser's "Back" or "Forward" buttons.
Explicit navigation results in both pagebeforechange events being triggered before a new entry is added to the browser's navigation history.
Implicit navigation results in both pagebeforechange events being triggered after the browser's navigation history has been updated.
In addition to the event parameter, handlers of this event will receive a second parameter, data. The second parameter is an object containing the following properties:
toPage (object or string)
options (object)
changePage() call.It should be noted that callbacks can modify both the toPage and options properties to alter the behavior of the current changePage() call. So for example, the toPage can be mapped to a different url from within a callback to do a sort of redirect.
The replacement for pagebeforechange is the pagecontainer widget's pagecontainerbeforechange event. In jQuery Mobile >= 1.4.3, the two events are identical except for their name and the fact that pagecontainerbeforechange is triggered on the pagecontainer, whereas pagebeforechange is triggered on the page.
Note: This event is part of the page widget as of jQuery Mobile 1.4.0. Please consult the documentation for the page widget's implementation.
The replacement for pagebeforehide is the pagecontainer widget's pagecontainerbeforehide event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainerbeforehide is triggered on the pagecontainer, whereas pagebeforehide is triggered on the page.
The replacement for pagebeforeload is the pagecontainer widget's pagecontainerbeforeload event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainerbeforeload is triggered on the pagecontainer, whereas pagebeforeload is triggered on the page.
The replacement for pagebeforeshow is the pagecontainer widget's pagecontainerbeforeshow event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainerbeforeshow is triggered on the pagecontainer, whereas pagebeforeshow is triggered on the page.
changePage() request has finished loading the page into the DOM and all page transition animations have completed. Note that any pageshow or pagehide events will have fired *BEFORE* this event is triggered. Callbacks for this particular event will be passed a data object as the 2nd arg. The properties for this object are as follows:
toPage (object or string)
options (object)
changePage() call.The replacement for pagechange is the pagecontainer widget's pagecontainerchange event. In jQuery Mobile >= 1.4.3, the two events are identical except for their name and the fact that pagecontainerchange is triggered on the pagecontainer, whereas pagechange is triggered on the page.
The replacement for pagechangefailed is the pagecontainer widget's pagecontainerchangefailed event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainerchangefailed is triggered on the pagecontainer, whereas pagechangefailed is triggered on the page.
body element. This limitation will be removed in future versions of jQuery Mobile.jQuery Mobile's central abstraction is the use of multiple pages inside a single HTML document. The children of the body are all div elements that have been enhanced into page widgets. These are jQuery Mobile pages.
Only one page is visible at a time. Upon navigation, the currently visible page is hidden, and another page is shown. Moving from one page to another is accomplished via a transition. This is not possible when navigating between HTML documents via HTTP, because the browser discards all state associated with the source page when navigating to the target page, making it impossible to perform this task via a smooth transition effect such as a fade or a slide.
In its simplest form, the HTML document retrieved by the browser has a body consisting of several div elements which are enhanced using the page widget. Each such page has an id attribute to distinguish it from other pages.
The pages can be interlinked using anchors. When the user clicks such an anchor, a new history entry is created, and the page to which the anchor refers is displayed by means of a smooth transition from the previous page. The example below illustrates a multipage setup. Note: If the example below animates using a fade transition instead of the slide transition requested in the anchor, it is because your browser does not support CSS 3D transforms.
<!doctype html>
<html>
<head>
<title>Multipage example</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="//code.jquery.com/mobile/1.5.0-alpha.1/jquery.mobile-1.5.0-alpha.1.min.css" />
<script src="//code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="//code.jquery.com/mobile/1.5.0-alpha.1/jquery.mobile-1.5.0-alpha.1.min.js"></script>
</head>
<body>
<div data-role="page" id="page1">
<div data-role="header">
<h1>Page 1</h1>
</div>
<div role="main" class="ui-content">
<a href="#page2" data-transition="slide" class="ui-btn ui-corner-all ui-btn-inline">Go To Page 2</a>
</div>
</div>
<div data-role="page" id="page2">
<div data-role="header">
<h1>Page 2</h1>
</div>
<div role="main" class="ui-content">
<a href="#page1" data-rel="back" data-transition="slide" class="ui-btn ui-corner-all ui-btn-inline">Go Back To Page 1</a>
</div>
</div>
</body>
</html>
jQuery Mobile allows you to replace the browser's standard HTTP navigation with Ajax-based navigation. It overrides the browser's default link handling behavior. It intercepts clicks on anchors containing links to other documents and upon each such click it checks whether the document can be retrieved via Ajax. A link has to meet the following criteria in order for the document to which it links to be retrieved via Ajax:
$.mobile.linkBindingEnabled must be true.data-rel="back"data-rel="externaldata-ajax="false"target attribute must not be present$.mobile.ajaxEnabled must be true.If these criteria are met jQuery Mobile retrieves the document via Ajax. It is important to realize that, while the document is retrieved in its entirety, only the first jQuery Mobile page is displayed. The header and the rest of the body are discarded. Thus, it is not possible to retrieve a multi-page document via Ajax, nor is it possible to execute scripts located in the header.
After Ajax retrieval, jQuery Mobile displays the page via a transition. The transition can be specified on the link that opens the page using the data-transition attribute. If no transition is specified, then $.mobile.defaultPageTransition is used or, if the incoming page is a dialog, then $.mobile.defaultDialogTransition is used.
If the browser supports the replaceState API the location bar is updated such that it displays the URL of the document that was retrieved via Ajax. This latter step has the following implications for site/application design:
pagecreate event.change() callCallbacks bound to this event can call preventDefault() on the event to indicate that they are handling the load request. Callbacks that do this MUST make sure they call resolve() or reject() on the deferred object reference contained in the object passed to the callback via its ui parameter.
preventDefault() on the event MUST call resolve() or reject() on this object so that change() requests resume processing. Deferred object observers expect the deferred object to be resolved like this:
$( document ).on( "pagecontainerbeforeload", function( event, data ) {
// Let the framework know we're going to handle the load.
event.preventDefault();
// ... load the document then insert it into the DOM ...
// at some point, either in this callback, or through
// some other async means, call resolve, passing in
// the following args, plus a jQuery collection object
// containing the DOM element for the page.
data.deferred.resolve( data.absUrl, data.options, page );
});
or rejected like this:
$( document ).on( "pagecontainerbeforeload", function( event, data ) {
// Let the framework know we're going to handle the load.
event.preventDefault();
// ... load the document then insert it into the DOM ...
// at some point, if the load fails, either in this
// callback, or through some other async means, call
// reject like this:
data.deferred.reject( data.absUrl, data.options );
});
change() call.change() request fails to load the page.change() call that triggered the event.change() call.pagehide event, this event is not triggered on the "fromPage" but the pagecontainer widget's element.
Note that this event will not be dispatched during the transition of the first page at application startup since there is no previously active page.
You can access the nextPage properties via the second argument of a bound callback function. For example:
$( ":mobile-pagecontainer" ).on( "pagecontainerhide", function( event, ui ) {
alert( "This page was just shown: " + ui.nextPage );
});
For these handlers to be invoked during the initial page load, you must bind them before jQuery Mobile executes. This can be done in the mobileinit handler, as described on the global config page.
$.ajax() success callback.$.ajax() error callback. It may also be null.By default, after dispatching this event, the framework will display a page failed message and call reject() on the deferred object contained within the event's ui parameter. Callbacks can prevent this default behavior from executing by calling preventDefault() on the event.
preventDefault() on the event, MUST call resolve() or reject() on this object so that change() requests resume processing. Deferred object observers expect the deferred object to be resolved like this:
$( document ).on( "pageloadfailed", function( event, data ) {
// Let the framework know we're going to handle things.
event.preventDefault();
// ... attempt to load some other page ...
// at some point, either in this callback, or through
// some other async means, call resolve, passing in
// the following args, plus a jQuery collection object
// containing the DOM element for the page.
data.deferred.resolve( data.absUrl, data.options, page );
});
or rejected like this:
$( document ).on( "pageloadfailed", function( event, data ) {
// Let the framework know we're going to handle things.
event.preventDefault();
// ... attempt to load some other page ...
// at some point, if the load fails, either in this
// callback, or through some other async means, call
// reject like this:
data.deferred.reject( data.absUrl, data.options );
});
$.ajax() error callback.null, are "timeout", "error", "abort", and "parsererror". This is what gets passed as the 2nd argument to the framework's $.ajax() error callback.null. This is what gets passed as the 3rd argument to the framework's $.ajax() error callback.pageshow event, this event is not triggered on the "toPage" but the pagecontainer widget's element.
You can access the prevPage properties via the second argument of a bound callback function. For example:
$( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) {
alert( "This page was just hidden: " + ui.prevPage );
});
For these handlers to be invoked during the initial page load, you must bind them before jQuery Mobile executes. This can be done in the mobileinit handler, as described on the global config page.
$( ":mobile-pagecontainer" ).pagecontainer( "change", "confirm.html", { role: "dialog" } );
change() ignores requests to change to the current active page. Setting this option to true allows the request to execute. Developers should note that some of the page transitions assume that the fromPage and toPage of a change() request are different, so they may not animate as expected. Developers are responsible for either providing a proper transition, or turning it off for this specific case.
| true | The pagecontainer will create a browser history entry as part of moving to the desired page. Thus, the user can use the browser's "Back" and "Forward" buttons to navigate between the source page and the destination page. |
| false | The pagecontainer will navigate to the desired page without creating a new browser history entry. The desired page replaces the current page, and the browser's "Back" and "Forward" buttons cannot be used to navigate between the source page and the destination page. |
change() completion. If not specified, the value of the data-url attribute of the page element is used.Note: This property is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Use property reload instead.
Whether to force a reload of the page even when it is already in the DOM. Used only when the 'url' argument is a URL.
true you can simulate returning to a previous page, even when the actual navigation sequence is in a forward direction.undefined which means rely on the value of the @data-role attribute defined on the element.undefined, the value of $.mobile.defaultPageTransition (currently "fade") will be used for pages, and $.mobile.defaultDialogTransition (currently "pop") will be used for dialogs.
Default value: undefined
$( ":mobile-pagecontainer" ).pagecontainer( "load", "confirm.html", { role: "dialog" } );
Note: This property is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Use property reload instead.
Whether to force a reload of the page even when it is already in the DOM. Used only when the 'url' argument is a URL.
undefined which means rely on the value of the @data-role attribute defined on the element.Note:This event is part of the page widget as of jQuery Mobile 1.4.0. Please consult the documentation for the page widget's implementation.
The replacement for pagehide is the pagecontainer widget's pagecontainerhide event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainerhide is triggered on the pagecontainer, whereas pagehide is triggered on the page.
We recommend binding to this event instead of DOM ready() because this will work regardless of whether the page is loaded directly or if the content is pulled into another page as part of the Ajax navigation system.
$( document ).on( "pageinit", "#aboutPage", function( event ) {
alert( "This page was just enhanced by jQuery Mobile!" );
});
pagecreate. Simply replace pageinit in the above example.The replacement for pageload is the pagecontainer widget's pagecontainerload event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainerload is triggered on the pagecontainer, whereas pageload is triggered on the page.
The replacement for pageloadfailed is the pagecontainer widget's pagecontainerloadfailed event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainerloadfailed is triggered on the pagecontainer, whereas pageloadfailed is triggered on the page.
By default, the framework removes any non active dynamically loaded external pages from the DOM as soon as the user navigates away to a different page. The pageremove event is dispatched just before the framework attempts to remove the page from the DOM.
This event is triggered just before the framework attempts to remove an external page from the DOM. Event callbacks can call preventDefault on the event object to prevent the page from being removed.
The replacement for pageremove is the pagecontainer widget's pagecontainerremove event. In jQuery Mobile >= 1.4.3, the two events are identical except for their name and the fact that pagecontainerremove is triggered on the pagecontainer, whereas pageremove is triggered on the page.
The replacement for pageshow is the pagecontainer widget's pagecontainershow event. In jQuery Mobile 1.4.0, the two events are identical except for their name and the fact that pagecontainershow is triggered on the pagecontainer, whereas pageshow is triggered on the page.
Panels are designed to be as flexible as possible to make it easy to create menus, collapsible columns, drawers, inspectors panes and more.
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.
Here is an example of the panel before the header, content and footer in the source order:
<div data-role="page">
<div data-role="panel" id="mypanel">
<!-- panel content goes here -->
</div><!-- /panel -->
<!-- header -->
<!-- content -->
<!-- footer -->
</div><!-- page -->
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.
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:
-webkit-transform: translate3d( 0, 0, 0 );
Since jQuery Mobile 1.4.0, it is also possible to have external panels. This means that you can now have panels located outside the page. Panels outside of a page must be initalized manually and will not be handled by auto init. Panels outside of pages will remain in the DOM (unless manually removed) as long as you use Ajax navigation, and can be opened or closed from any page. This can be handy when you want to use the same panel on more than one page.
Here is an example of an external panel:
<div data-role="page">
<!-- header -->
<!-- content -->
<!-- footer -->
</div><!-- page -->
<div data-role="panel" id="mypanel">
<!-- panel content goes here -->
</div><!-- /panel -->
The panel can be enhanced manually as follows:
$( function() {
$( "#mypanel" ).panel();
} );
Note that if the panel contains other jQuery Mobile widgets, such as listviews, these will need to be enhanced manually as well.
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:
<div data-role="panel" id="mypanel">
<!-- panel content goes here -->
</div>
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:
<div data-role="panel" id="mypanel" data-position="right" data-display="push">
<!-- panel content goes here -->
</div>
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.
$( "#mypanel" ).trigger( "updatelayout" );
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.
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:
$( "#idofpanel" ).panel( "open" , optionsHash );
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.
<a href="#mypanel">Open panel</a>
When using markup to control panels, you can only have a single panel open at once. Clicking a link to open a panel while one is already open will auto-close the first. This is done to keep the markup-only configuration simple.
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.
$( "#idofpanel" ).panel( "close" );
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:
<a href="#my-header" data-rel="close">Close panel</a>
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.
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.
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-panel-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-panel-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 "a". 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.
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):
@media (min-width:35em) {
/* wrap on wide viewports once open */
.ui-panel-page-content-open.ui-panel-page-content-position-left {
margin-right: 17em;
}
.ui-panel-page-content-open.ui-panel-page-content-position-right {
margin-left: 17em;
}
.ui-panel-page-content-open {
width: auto;
}
/* disable "dismiss" on wide viewports */
.ui-panel-dismiss {
display: none;
}
/* same as the above but for panels with display mode "push" only */
.ui-panel-page-content-open.ui-panel-page-content-position-left.ui-panel-page-content-display-push {
margin-right: 17em;
}
.ui-panel-page-content-open.ui-panel-page-content-position-right.ui-panel-page-content-display-push {
margin-left: 17em;
}
.ui-panel-page-content-open.ui-panel-page-content-display-push {
width: auto;
}
.ui-panel-dismiss-display-push {
display: none;
}
}
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 (not the panel).
To create a popup, add the data-role="popup" attribute to a div with the popup contents. Then create a link with the href set to the id of the popup div, and add the attribute data-rel="popup" to tell the framework to open the popup when the link is tapped. This is a similar markup pattern to the dialog widget. A popup div has to be nested inside the same page as the link.
The popup widget uses the jQuery Mobile CSS framework to style its look and feel. If popup specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-popup-container: Outermost container for listview widget. Additionally, ui-popup-active class will be added when popup is active and ui-popup-hidden, ui-popup-truncate classes will be added when popup is inactive.
ui-popup: Main container of popup which withhelds all the content
ui-popup-arrow-guide: Guide of the arrow.
ui-popup-arrow-container: Container for the arrow of the popup. This will additionally have ui-popup-arrow-l, ui-popup-arrow-t, ui-popup-arrow-r, ui-popup-arrow-b classes accordingly if arrow is set to left, top, right or bottom respectively.
ui-popup-arrow: Main arrow element
<a href="#popupBasic" data-rel="popup">Open Popup</a>
<div data-role="popup" id="popupBasic">
<p>This is a completely basic popup, no options set.</p>
</div>
This will result in the following popup:
The popup consists of two elements: the screen, which is a transparent or translucent element that covers the entire document, and the container, which is the popup itself. If your original element had an id attribute, the screen and the container will each receive an id attribute based on it. The screen's id will be suffixed with "-screen", and the container's id will be suffixed with "-popup" (in the above example, id="popupBasic-screen" and id="popupBasic-popup", respectively).
The framework adds a small amount of margin to text elements, but it's really just a container with rounded corners and a shadow which serves as a blank slate for your designs (even these features can be disabled via options). Please note that if you want to add a header to the popup and also have a closing button, the markup for the header must come first.
This simple styling makes it easy to add in widgets to create a variety of different interactions. Here are a few real-world examples that combine the various settings and styles you can achieve out of the box with popups:
The framework CSS contains rules that make images that are immediate children of the popup scale to fit the screen. Because of the absolute positioning of the popup container and screen, the height is not adjusted to screen height on all browsers. You can prevent vertical scrolling with a simple script that sets the max-height of the image.
In the two examples below the divs with data-role="popup" have a class of photopopup.
The handler is bound to the popupbeforeposition event, which ensures the image is not only scaled before it is shown but also when the window is resized (e.g. orientation change). In this code example the height is reduced by 60 to take a top and bottom tolerance of 30 pixels into account.
$( document ).on( "pagecreate", function() {
$( ".photopopup" ).on({
popupbeforeposition: function() {
var maxHeight = $( window ).height() - 60 + "px";
$( ".photopopup img" ).css( "max-height", maxHeight );
}
});
});
You may need to embed an iframe into a popup to use a 3rd party widget. Here, we'll walk through a few real-world examples of working with iframes: videos and maps.
Here is an example of a 3rd party video player embedded in a popup:
The markup is an iframe inside a popup container. The popup will have a 15 pixels padding because of class ui-content and a one pixel border because the framework will add class ui-body-a to the popup.
<div data-role="popup" id="popupVideo" data-overlay-theme="b" data-theme="a" data-tolerance="15,15" class="ui-content">
<iframe src="http://player.vimeo.com/video/41135183" width="497" height="298" seamless></iframe>
</div>
When using an iframe inside a popup it is important to initially set the width and height attributes to 0. This prevents the page to breaking on platforms like Android 2.3. Note that you have to set the attributes, because setting the width and height with CSS is not sufficient. You can leave the actual width and height in the markup for browsers that have JavaScript disabled and use attr() to set the zero values upon the pageinit event.
Next, bind to the popupbeforeposition event to set the desired size of the iframe when the popup is shown or when the window is resized (e.g. orientation change). For the iframe examples on this page a custom function scale() is used to scale down the iframe to fit smaller screens. Expand the section below to view the code of this function.
scale()The window width and height are decreased by 30 to take the tolerance of 15 pixels at each side into account.
function scale( width, height, padding, border ) {
var scrWidth = $( window ).width() - 30,
scrHeight = $( window ).height() - 30,
ifrPadding = 2 * padding,
ifrBorder = 2 * border,
ifrWidth = width + ifrPadding + ifrBorder,
ifrHeight = height + ifrPadding + ifrBorder,
h, w;
if ( ifrWidth < scrWidth && ifrHeight < scrHeight ) {
w = ifrWidth;
h = ifrHeight;
} else if ( ( ifrWidth / scrWidth ) > ( ifrHeight / scrHeight ) ) {
w = scrWidth;
h = ( scrWidth / ifrWidth ) * ifrHeight;
} else {
h = scrHeight;
w = ( scrHeight / ifrHeight ) * ifrWidth;
}
return {
'width': w - ( ifrPadding + ifrBorder ),
'height': h - ( ifrPadding + ifrBorder )
};
};
Note: This function is not part of the framework. Copy the code into your script to use it.
When the popup is closed the width and height should be set back to 0. You can do this by binding to the popupafterclose event.
This is the complete script and the link to open the video popup:
$( document ).on( "pageinit", function() {
$( "#popupVideo iframe" )
.attr( "width", 0 )
.attr( "height", 0 );
$( "#popupVideo" ).on({
popupbeforeposition: function() {
var size = scale( 497, 298, 15, 1 ),
w = size.width,
h = size.height;
$( "#popupVideo iframe" )
.attr( "width", w )
.attr( "height", h );
},
popupafterclose: function() {
$( "#popupVideo iframe" )
.attr( "width", 0 )
.attr( "height", 0 );
}
});
});
Note that the video will still be playing in the iframe when the popup is closed. If available you can use the 3rd party API to stop the video on the popupafterclose event. Another way is to create the iframe when the popup is opened and destroy it when the popup is closed, but this would drop support for browsers that have JavaScript disabled.
In the second example, an iframe is used to display Google Maps API. Using an iframe prevents issues with the controls of the map.
This is the markup of the popup including a right close button:
<div data-role="popup" id="popupMap" data-overlay-theme="b" data-theme="b" data-corners="false" data-tolerance="15,15">
<a href="#" data-rel="back" data-role="button" data-theme="b" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
<iframe src="map.html" width="480" height="320" seamless></iframe>
</div>
Expand the section below to view the source of the iframe.
map.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Map</title>
<script>
function initialize() {
var myLatlng = new google.maps.LatLng( 51.520838, -0.140261 );
var myOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map( document.getElementById( "map_canvas" ), myOptions );
}
</script>
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<style>
html {
height: 100%;
overflow: hidden;
}
body {
margin: 0;
padding: 0;
height: 100%;
}
#map_canvas {
height: 100%;
}
</style>
</head>
<body onload="initialize()">
<div id="map_canvas"></div>
</body>
</html>
Setting the size of the iframe is done exactly the same as for the video example, with one exception. You should also set the width and height of the div that contains the map to prevent the page from breaking on platforms like Android 2.3. In this example the ID of this div is #map_canvas.
This is the complete script and the link to open the map popup:
$( document ).on( "pageinit", function() {
$( "#popupMap iframe" )
.attr( "width", 0 )
.attr( "height", 0 );
$( "#popupMap iframe" ).contents().find( "#map_canvas" )
.css( { "width" : 0, "height" : 0 } );
$( "#popupMap" ).on({
popupbeforeposition: function() {
var size = scale( 480, 320, 0, 1 ),
w = size.width,
h = size.height;
$( "#popupMap iframe" )
.attr( "width", w )
.attr( "height", h );
$( "#popupMap iframe" ).contents().find( "#map_canvas" )
.css( { "width": w, "height" : h } );
},
popupafterclose: function() {
$( "#popupMap iframe" )
.attr( "width", 0 )
.attr( "height", 0 );
$( "#popupMap iframe" ).contents().find( "#map_canvas" )
.css( { "width": 0, "height" : 0 } );
}
});
});
This plugin will autoinitialize on any page that contains a div with the attribute data-role="popup". However, if needed you can directly call the popup plugin on any selector, just like any jQuery plugin and programmatically work with the popup options, methods, and events API:
$( "#myPopupDiv" ).popup();
Using the markup-based configuration, when a link with the data-rel="popup" is tapped, the corresponding popup container with the id referenced in the href of the link will be shown. To open a popup programmatically, call popup with the open method on the popup container:
$( "#myPopupDiv" ).popup( "open" )
By default popups can be closed either by clicking outside the popup widget or by pressing the Esc key. To prevent this, the data-dismissible="false" attribute can be added to the popup. Popups can also be closed via the close method:
$( "#myPopupDiv" ).popup( "close" )
To add an explicit close button to a popup, add a link with the role of button into the popup container with a data-rel="back" attribute which will close the popup when tapped. We have created helper classes to position buttons in the upper left (ui-btn-left) or upper right (ui-btn-right) of the popup but you may need to tweak these or add custom positioning styles depending on your design. We recommend adding standard content padding to the popup to make room for the buttons (see next section).
<div data-role="popup">
<a href="#" data-rel="back" data-role="button" data-theme="a" data-icon="delete" data-iconpos="notext" class="ui-btn-right">Close</a>
...popup contents go here...
</div>
For popups with formatted text, padding is needed. We recommend adding the ui-content class to the popup container which adds the standard 1em (16px) of padding, just like the page content container. Write your own styles to create a more customized design if needed.
<a href="#popupPadded" data-rel="popup" data-role="button">Popup with padding</a>
<div data-role="popup" id="popupPadded" class="ui-content">
<p>This is a popup with the <code>ui-content</code> class added to the popup container.</p>
</div>
This will result in the following popup with content padding:
When padding is added, we apply a few style rules to negate the top margin for the first heading or paragraph in the popup and do the same for the last element's bottom margin. This keep the popups from having too much vertical space when the content padding and element margins combine.
By default, popups open centered vertically and horizontally over the thing you clicked (the origin) which is good for popups used as tooltips or menus. The framework also applies some basic collision detection rules to ensure that the popup will appear on-screen so the ultimate position may not always be centered over the origin.
For situations like a dialog or lightbox where the popup should appear centered within the window instead of over the origin, add the data-position-to attribute to the link and specify a value of window.
It's also possible to specify any valid selector as the value of position-to in addition to origin and window. For example, if you add data-position-to="#myElement" the popup will be positioned over the element with the id myElement.
A few examples:
The popup's placement constraints, which may cause the popup not to appear centered as desired, are as follow:
max-width to the width of the window minus a tolerance of 15px on either side.Also note that a popup is currently always placed at the center of the window after an orientation change or window resize event.
See methods for information about setting the popup position programmatically, including the option to specify x and y coordinates.
By default, popups have no transition to make them open as quickly as possible. To set the transition used for a popup, add the data-transition attribute to the link that references the popup. The reverse version of the transition will be used when closing the popup.
<a href="#transitionExample" data-transition="flip" data-rel="popup">
Flip transition
</a>
For performance reasons on mobile devices, we recommend using simpler transitions like pop, fade or none for smooth and fast popup animations, especially with larger or complex widgets within a popup. To view all transition types, you must be on a browser that supports 3D transforms. By default, devices that lack 3D support (such as Android 2.x) will fallback to "fade" for all transition types. See the transitions page for detailed information on the transition system.
When you launch the popup from any of the buttons, the data-transition set on the button will be used. However, if you launch the popup programmatically, such as via $( "#transitionExample" ).popup( "open" ), the data-transition attribute specified in the definition of the popup will be used if present.
The popup plugin provides two theme-related options: data-theme and data-overlay-theme. The data-theme option refers to the theme of the popup itself, whereas data-overlay-theme refers to the theme of the popup's background, which covers the entire window behind the popup.
data-theme will be inherited from the page, and will always have a valid value when the popup opens, unless you explicitly specify data-theme="none", in which case the popup will have a transparent background.
The data-overlay-theme will never be set, and the popup's background, although always present when the popup is shown, will be completely transparent, unless explicitly set using for example data-overlay-theme="b". In this case, the background will fade in, partially obscuring the rest of the window, to further direct attention to the popup. Here is an example of an explicitly themed popup:
<div id="both" data-role="popup" data-theme="b" data-overlay-theme="a" class="ui-content">
...Popup contents...
</div>
The extension widgets/popup.arrow provides the arrow option, which is also exposed as a data attribute. For example, data-arrow="t,b" will result in the popup being displayed with a top or a bottom arrow.
When an arrow is requested using the arrow option, the popup is positioned along one of the edges of the popup such that the arrow points at the center of the origin. The value of the arrow option is a comma-separated list of letters referring to the edges of the popup along which the framework should attempt to place the arrow:
| t | The framework should attempt to place the popup such that the arrow somewhere along the top edge of the popup points at the center of the origin. |
| r | The framework should attempt to place the popup such that the arrow somewhere along the right edge of the popup points at the center of the origin. |
| b | The framework should attempt to place the popup such that the arrow somewhere along the bottom edge of the popup points at the center of the origin. |
| l | The framework should attempt to place the popup such that the arrow somewhere along the left edge of the popup points at the center of the origin. |
For each edge given in the list, the framework calculates
The example below shows a popup with an arrow either along its left edge or along its top edge.
<div data-role="popup" data-arrow="l,t" class="ui-content">
<h2>Popup with an arrow</h2>
<p>A second paragraph.</p>
</div>
data-rel="popup" inside a popup will not do anything at all.This also means that custom select menus will not work inside popups, because they are themselves implemented using popups. If you place a select menu inside a popup, it will be rendered as a native select menu, even if you specify data-native-menu="false".
A workaround to get chained popups working is the use of a timeout for example in the popupafterclose event bound to the invoking popup. In the following example, when the first popup is closed, the second will be opened by a delayed call to the open method:
$( document ).on( "pageinit", function() {
$( ".popupParent" ).on({
popupafterclose: function() {
setTimeout(function() { $( ".popupChild" ).popup( "open" ) }, 100 );
}
});
});
You can improve the load time of your page by providing the markup that the popup widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the popup widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The popup widget moves the element on which it is instantiated such that it becomes the last child element of a page div or, if the element is not inside a page, it will become the last child element of the body. It then wraps the element in a container div, and prepends a newly created element that serves as the modal overlay screen to the parent of the container.
The example below includes an entire jQuery Mobile page rather than just the popup. This helps illustrate where you must place the markup for the pre-rendered popup widget in relation to the jQuery Mobile page on which it is to appears. In the example, the popup has the attribute data-overlay-theme="b" to reflect the fact that the modal overlay screen has an associated theme.
<div data-role="page">
<div data-role="header">
<h1>Example Page</h1>
</div>
<div role="main" class="ui-content">
<a href="#pre-rendered" data-rel="popup" class="ui-btn ui-corner-all ui-shadow ui-btn-inline">Open pre-rendered popup</a>
</div>
<!-- the following two divs represent the pre-rendered popup widget -->
<div class="ui-popup-screen ui-overlay-b ui-screen-hidden"></div>
<div class="ui-popup-container ui-popup-hidden ui-popup-truncate" id="pre-rendered-popup">
<div class="ui-popup ui-body-inherit ui-overlay-shadow ui-corner-all" id="pre-rendered" data-role="popup" data-enhanced="true" data-overlay-theme="b">
<p>Pre-rendered popup</p>
</div>
</div>
</div>
The popup widget adds an ID to the elements it generates. The ID for any given generated element is constructed by suffixing the popup's own ID:
<popup-id>-placeholder<popup-id>-screen<popup-id>-popupFor example, creating a popup with
<div id="extra-info" data-role="popup">
<p>To use this feature, enable it from Settings.</p>
</div>
will result in the following markup:
<div id="extra-info-placeholder" style="display: none;">
<!-- placeholder for extra-info -->
</div>
<div id="extra-info-screen" class="ui-screen-hidden ui-popup-screen ui-overlay-inherit"></div>
<div id="extra-info-popup" class="ui-popup-container ui-popup-hidden ui-popup-truncate">
<div id="extra-info" data-role="popup" class="ui-popup ui-body-inherit ui-overlay-shadow ui-corner-all">
<p>To use this feature, enable it from Settings.</p>
</div>
</div>
Triggered when a popup has completely closed
This event is triggered when the popup has completely disappeared from the screen, meaning that all associated animations have completed.
Triggered after a popup has completely opened
This event is triggered when the popup has completely appeared on the screen, meaning that all associated animations have completed.
Triggered before a popup computes the coordinates where it will appear
This event is triggered when the popup has completed preparations for appearing on the screen, when the document is resized and the popup needs to move to another location, or when the reposition() method is called. At this point the popup has not yet started the opening animations and it has not yet calculated the coordinates where it will appear on the screen. Handling this event gives an opportunity to modify the content of the popup before it appears on the screen. For example, the content can be scaled or parts of it can be hidden or removed if it is too wide or too tall. You can also modify the options parameter to affect the popup's placement. The properties inside the options object available for modification are the same as those used by the reposition method.
If the x or y option is missing, and no jQuery selector is given as the value of the positionTo option, the middle of the window will be used.
The transition option can be used to override the popup's own transition option. This will result in the popup opening via the transition specified in the call, but the popup's transition option will not be updated.
Similarly, the positionTo option can be used to override the popup's default positioning without modifying the value of the popup's positionTo option. The values available for positionTo are the same as those for the popup's positionTo option.
optionName.optionName.open() method for a description of the keys recognized from the options object.The rangeslider widget can be considered as a double handle slider. To add a rangeslider widget to your page, use two standard inputs with the type="range" attribute, and put them inside a <div> container. The input values are used to configure the starting position of the handles and the values are populated in the corresponding text inputs (the first one at the beginning of the rangeslider, and the second one at the end). Specify min and max attribute values to set the rangeslider's range. If you want to constrain inputs to specific increments, add the step attribute. Set the value attribute on each input to define their initial value. The framework will parse these attributes to configure the rangeslider widget.
As you drag the rangeslider's handles, the framework will update the native input values (and vice-versa) so they are always in sync; this ensures that the values are submitted with the form.
Set the for attribute of the labels to match the ids of the inputs so they are semantically associated. It's possible to accessibly hide the labels if they're not desired in the page layout, but we require that they are present in the markup for semantic and accessibility reasons.
The framework will find all input elements with a type="range" and automatically enhance them into a slider with an accompanying input without any need to apply a data-role attribute. To prevent the automatic enhancement of this input into a slider, add the data-role="none" attribute to the inputs.
The rangeslider widget uses the jQuery Mobile CSS framework to style its look and feel. If rangeslider specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-rangeslider: The outermost container for rangeslider.
ui-slider-popup: Tooltip popup element in case data-popup-enabled is true
ui-slider-first: Opening range input element of rangeslider
ui-slider-last: Closing range input element of rangeslider
ui-rangeslider-sliders: Sliders for rangeslider
In this example, the acceptable range is 0-100.
<div data-role="rangeslider">
<label for="range-1a">Rangeslider:</label>
<input name="range-1a" id="range-1a" min="0" max="100" value="0" type="range" />
<label for="range-1b">Rangeslider:</label>
<input name="range-1b" id="range-1b" min="0" max="100" value="100" type="range" />
</div>
The default rangeslider with these settings is displayed like this:
To force the range to snap to a specific increment, add the step attribute to the input. By default, the step is 1, but in this example, the step is 0.1 and the maximum value is 10.
In this example, the acceptable range is 0-100.
<div data-role="rangeslider">
<label for="range-10a">Rangeslider:</label>
<input name="range-10a" id="range-10a" min="0" max="10" step=".1" value="0" type="range" />
<label for="range-10b">Rangeslider:</label>
<input name="range-10b" id="range-10b" min="0" max="10" step=".1" value="10" type="range" />
</div>
This will produce an input that snaps to increments of 0.1. If a value is added to the input that isn't valid with the step increment, the value will be reset on blur to the closest step.
By default, there is a highlight fill on the track between the two slider handles. To remove it, add the data-highlight="false" attribute to the input. The fill uses the active state swatch.
<div data-role="rangeslider" data-highlight="false">
<label for="range-2a">Rangeslider (default is "true"):</label>
<input name="range-2a" id="range-2a" min="0" max="100" value="0" type="range" />
<label for="range-2b">Rangeslider:</label>
<input name="range-2b" id="range-2b" min="0" max="100" value="100" type="range" />
</div>
To set the theme swatch for the rangeslider, add a data-theme attribute to the inputs which will apply the theme to the inputs, handles and track. The track swatch can be set separately by adding the data-track-theme attribute to apply the down state version of the selected button swatch.
<div data-role="rangeslider" data-track-theme="a" data-theme="b">
<label for="range-3a">Rangeslider:</label>
<input name="range-3a" id="range-3a" min="0" max="100" value="0" type="range" />
<label for="range-3b">Rangeslider:</label>
<input name="range-3b" id="range-3b" min="0" max="100" value="100" type="range" />
</div>
This will produce a themed rangeslider:
For a more compact version that is useful in toolbars and tight spaces, add the data-mini="true" attribute to the element to create a mini version.
<div data-role="rangeslider" data-mini="true">
<label for="range-4a">Rangeslider:</label>
<input name="range-4a" id="range-4a" min="0" max="100" value="0" type="range" />
<label for="range-4b">Rangeslider:</label>
<input name="range-4b" id="range-4b" min="0" max="100" value="100" type="range" />
</div>
This will produce a rangeslider and its corresponding inputs that are not as tall as the standard version. The inputs also have a smaller text size.
Optionally wrap the rangeslider markup in a container with class ui-field-contain to help visually group it in a longer form. In this example, the step attribute is omitted to allow any whole number value to be selected.
Note: The data- attribute data-role="fieldcontain" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Use the ui-field-contain class instead.
<div class="ui-field-contain">
<div data-role="rangeslider">
<label for="range-7a">Rangeslider:</label>
<input name="range-7a" id="range-7a" min="0" max="100" value="0" type="range" />
<label for="range-7b">Rangeslider:</label>
<input name="range-7b" id="range-7b" min="0" max="100" value="100" type="range" />
</div>
</div>
The rangeslider is now displayed like this:
Sliders also respond to key commands. Right Arrow, Up Arrow and Page Up keys increase the value; Left Arrow, Down Arrow and Page Down keys decrease it. To move the slider to its minimum or maximum value, use the Home or End key, respectively.
This plugin will auto initialize on any page that contains a div with the data-role="rangeslider" attribute. However, if needed you can directly call the rangeslider plugin on any selector, just like any jQuery plugin:
$( "div#range-slider" ).rangeslider();
optionName.optionName.If you manipulate a rangeslider via JavaScript, you must call the refresh method on it to update the visual styling.
When using layout grids for building full-level layouts, it may make sense to apply responsive web design (RWD) principles to ensure that the layout adapts to a wide range screen widths.
The simplest form of responsive behavior swaps from a stacked layout on narrow screens like a smartphone to the multi-column grid layouts at wider screens. This can be done by targeting styles to specific screen widths by using CSS media queries.
By default, the grid classes will result in a multi column layout across all screen widths. The styles to make the grids responsive are added by applying a media query with rules to switch to the stacked style presentation below a specific screen width.
We normally recommend starting with mobile-first approach for media queries: starting with the styles that apply to the smallest screen sizes in the core widget styles, then progressively layering breakpoints up to larger screens by using min-width media queries.
However, in the case of grids we can use a max-width media query to only apply the stacked grid styles below a width breakpoint. This allows us to leverage all the default grid styles but just tweak them at narrow widths.
Without the custom styles, our grid will be a 3 column layout across all screen widths:
In our custom styles, we want this grid to stack at narrow widths, then switch to a standard 3 column layout. At very wide screen widths, we want first column to take up 50% of the width, like this:
To make this responsive, start by adding the my-breakpoint class to the grid container that references the custom breakpoint in your custom stylesheet:
<div class="ui-grid-b my-breakpoint">
<div class="ui-block-a">Block A</div>
<div class="ui-block-b">Block B</div>
<div class="ui-block-c">Block C</div>
</div><!-- /grid-b -->
This class is used to scope the styles within the custom media query so they will only apply when this class is added to the grid container. The media query wraps the conditional styles we only want applied below 50em.
In your media queries, use em units instead of pixels to ensure that the media query will take font size into account in addition to just screen width. To calculate a screen widths in ems, divide the target width in pixels by 16 which is the default font size of the body.
@media all and (max-width: 50em) {
.my-breakpoint .ui-block-a,
.my-breakpoint .ui-block-b,
.my-breakpoint .ui-block-c,
.my-breakpoint .ui-block-d,
.my-breakpoint .ui-block-e {
width: 100%;
float:none;
}
}
Within this media query, we set the width to 100% and negate the float property to make the grid blocks stack below 50em screen widths. These rules are applied to every grid type by stacking up selectors for all the grid classes from ui-block-a to ui-block-e on the styles.
That is all it takes to make grids responsive and it's easy to add additional styling rules to each breakpoint to change it up even more. We encourage you to create as many custom breakpoints as you need based on your unique content and layout needs.
Building on the example above, we can add an additional breakpoint to shift the widths to make the first column 50% width and the other two 25% above 75em (1,200 pixels) by layering an additional min-width media query to tweak widths in our custom style like this:
@media all and (min-width: 75em) {
.my-breakpoint.ui-grid-b .ui-block-a { width: 49.95%; }
.my-breakpoint.ui-grid-b .ui-block-b,
.my-breakpoint.ui-grid-b .ui-block-c { width: 24.925%; }
.my-breakpoint.ui-grid-b .ui-block-a { clear: left; }
}
}
Note the slightly narrower widths set to work around rounding issues across platforms.
Even though we strongly encourage you to write custom breakpoints yourself, the framework includes a single pre-configured breakpoint that targets the stacked style to smaller phones and swaps to the multi-column presentation on larger phones, tablet and desktop devices.
To use this preset breakpoint, add the ui-responsive class to the grid container to apply the stacked presentation below 560px (35em). If this breakpoint doesn't work for your content, we encourage you to write a custom breakpoint as described above.
<div class="ui-grid-b ui-responsive">
These are standard grids that are made responsive by ui-responsive class to the grid container:
Note that iOS devices freeze DOM manipulation during scroll, queuing them to apply when the scroll finishes. We're currently investigating ways to allow DOM manipulations to apply before a scroll starts.
The select menu is based on a native select element, which is hidden from view and replaced with a custom-styled select button that matches the look and feel of the jQuery Mobile framework. The select menu is ARIA-enabled and keyboard accessible on the desktop as well.
By default, the framework leverages the native OS options menu to use with the custom button. When the button is clicked, the native OS menu will open. When a value is selected and the menu closes, the custom button's text is updated to match the selected value. Please note that the framework also offers the possibility of having custom (non-native) select menus.
To add a select menu to your page, start with a standard select element populated with a set of option elements. Set the for attribute of the label to match the id of the select so they are semantically associated. It's possible to accessibly hide the label if it's not desired in the page layout, but we require that it is present in the markup for semantic and accessibility reasons.
The framework will find all select elements and automatically enhance them into select menus, no need to apply a data-role attribute. To prevent the automatic enhancement of a select, add data-role="none" attribute to the select.
The selectmenu widget uses the jQuery Mobile CSS framework to style its look and feel. If selectmenu specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-selectmenu: The outermost container for selectmenu.
ui-selectmenu-button: Custom styled button for the selectmenu
ui-selectmenu-button-icon: Selectmenu button icon
ui-selectmenu-button-text: Selectmenu button text
ui-selectmenu-custom: The outermost container for custom selectmenu.
ui-selectmenu-custom-list: List element for custom selectmenu
ui-selectmenu-custom-header-close-button: Close button for custom selectmenu
ui-selectmenu-custom-header-close-button-icom: Close button icon for custom selectmenu
<label for="select-choice-0" class="select">Shipping method:</label>
<select name="select-choice-0" id="select-choice-0">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
This will produce a basic select menu. The default styles set the width of the input to 100% of the parent container and stacks the label on a separate line.
For a more compact version that is useful in toolbars and tight spaces, add the data-mini="true" attribute to the element to create a mini version.
<label for="select-choice-min" class="select">Shipping method:</label>
<select name="select-choice-min" id="select-choice-min" data-mini="true">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
This will produce a select that a not as tall as the standard version and has a smaller text size.
Optionally wrap the selects in a container with class ui-field-contain to help visually group it in a longer form.
Note: The data- attribute data-role="fieldcontain" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Add class ui-field-contain instead.
<div class="ui-field-contain">
<label for="select-choice-1" class="select">Shipping method:</label>
<select name="select-choice-1" id="select-choice-1">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
</div>
The select input is now displayed like this:
An example of a select with a long list of options:
The following example organizes the options into optgroup elements. Support for this feature in mobile selects is a bit spotty, but is improving.
<div class="ui-field-contain">
<label for="select-choice-nc" class="select">Preferred delivery:</label>
<select name="select-choice-8" id="select-choice-nc">
<optgroup label="FedEx">
<option value="firstOvernight">First Overnight</option>
<option value="expressSaver">Express Saver</option>
<option value="ground">Ground</option>
</optgroup>
<optgroup label="UPS">
<option value="firstOvernight">First Overnight</option>
<option value="expressSaver">Express Saver</option>
<option value="ground">Ground</option>
</optgroup>
<optgroup label="US Mail">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day (disabled)</option>
<option value="overnight">Overnight</option>
</optgroup>
</select>
</div>
To create a grouped set of select inputs, first add select and a corresponding label. Set the for attribute of the label to match the id of the select so they are semantically associated.
Because the label element will be associated with each individual select input and will be hidden for styling purposes, we recommend wrapping the selects in a fieldset element that has a legend which acts as the combined label for the grouped inputs.
Lastly, one needs to wrap the fieldset in a div with data-role="controlgroup" attribute, so it can be styled as a group.
<div class="ui-field-contain">
<fieldset data-role="controlgroup">
<legend>Date of Birth:</legend>
<label for="select-choice-month">Month</label>
<select name="select-choice-month" id="select-choice-month">
<option>Month</option>
<option value="jan">January</option>
<!-- etc. -->
</select>
<label for="select-choice-day">Day</label>
<select name="select-choice-day" id="select-choice-day">
<option>Day</option>
<option value="1">1</option>
<!-- etc. -->
</select>
<label for="select-choice-year">Year</label>
<select name="select-choice-year" id="select-choice-year">
<option>Year</option>
<option value="2011">2011</option>
<!-- etc. -->
</select>
</fieldset>
</div>
Select inputs can also be used for grouped sets with more than one related selections. To make a horizontal button set, add the data-type="horizontal" to the fieldset. Note that the buttons which trigger the select will resize depending on the currently selected option’s value.
<fieldset data-role="controlgroup" data-type="horizontal">
You can specify any jQuery Mobile button data- attribute on a select element, too. In this example, we're setting the theme, icon and inline properties:
The framework is capable of building a custom menu based on the select element's list of options. We recommend using a custom menu when multiple selections are required, or when the menu itself must be styled with CSS.
You can optionally use custom-styled select menus instead of the native OS menu. The custom menu supports disabled options and multiple selection (whereas native mobile OS support for both is inconsistent), adds an elegant way to handle placeholder values, and restores missing functionality on certain platforms such as optgroup support on Android (all explained below). In addition, the framework applies the custom button's theme to the menu to better match the look and feel and provide visual consistency across platforms. Lastly, custom menus often look better on desktop browsers because native desktop menus are smaller than their mobile counterparts and tend to look disproportionate.
Keep in mind that there is overhead involved in parsing the native select to build a custom menu. If there are a lot of selects on a page, or a select has a long list of options, this can impact the performance of the page, so we recommend using custom menus sparingly.
To use custom menus on a specific select, just add the data-native-menu="false" attribute. Alternately, this can also programmatically set the select menu's nativeMenu configuration option to false in a callback bound to the mobileinit event to achieve the same effect. This will globally make all selects use the custom menu by default. The following must be included in the page after jQuery is loaded but before jQuery Mobile is loaded.
$(document).on( "mobileinit", function() {
$.mobile.selectmenu.prototype.options.nativeMenu = false;
});
When the select has a small number of options that will fit on the device's screen, the menu will appear as a small overlay with a pop transition:
When it has too many options to show on the device's screen, the framework will automatically create a new dialog-style "page" populated with a standard listview for the options. This allows us to use the native scrolling included on the device for moving through a long list. The text inside the label is used as the title for this page. Be aware of the page and pagecontainer events that will be fired for this generated page.
Note: The behavior whereby the custom select menu creates a new page when the list of options is long is deprecated as of jQuery Mobile 1.4.0. Starting with 1.5.0, the custom select menu will fall back to utilizing the select menu's native behavior when the list of options is too long.
jQuery Mobile will automatically disable and style option tags with the disabled attribute. In the demo below, the second option "Rush: 3 days" has been set to disabled.
It's common for developers to include a "null" option in their select element to force a user to choose an option. If a placeholder option is present in your markup, jQuery Mobile will hide them in the overlay menu, showing only valid choices to the user, and display the placeholder text inside the menu as a header. A placeholder option is added when the framework finds:
value=""). Note: Indicating that an option should be used as a placeholder by providing the value attribute and setting it to "" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0.
data-placeholder="true" attribute. (This allows you to use an option that has a value and a textnode as a placeholder option).You can disable this feature through the selectmenu plugin's hidePlaceholderMenuItems option, like this:
$.mobile.selectmenu.prototype.options.hidePlaceholderMenuItems = false;
Examples of various placeholder options:
If the multiple attribute is present in your markup, jQuery Mobile will enhance the element with a few extra considerations:
multiple attribute on a select with nativeMenu set to false.When a select is large enough to where the menu will open in a new page, the placeholder text is displayed in the button when no items are selected, and the label text is displayed in the menu's header. This differs from smaller overlay menus where the placeholder text is displayed in both the button and the header, and from full-page single selects where the placeholder text is not used at all.
If a select menu contains optgroup elements, jQuery Mobile will create a divider & group items based on the label attribute's text:
You can specify any jQuery Mobile button data- attribute on a select element, too. In this example, we're setting the theme, icon and inline properties:
The data-overlay-theme attribute can be added to a select element to set the color of the overlay layer for the dialog-based custom select menus and the outer border of the smaller custom menus. By default, the content block colors for swatch "a" will be used for the overlays.
Note: Custom selects use the popup widget for the menu. Because the popup container is elsewhere on the page it can't inherit the theme swatch from the parent of the select, and inherits from the page instead.
The select menu plugin will auto initialize on any page that contains a select menu, without any need for a data-role attribute in the markup. However, you can directly call the select menu plugin on any selector, just like any normal jQuery plugin:
$( "select" ).selectmenu();
The selectmenu widget adds an ID to the elements it generates. If it doesn't itself have an ID, it will use a prefix consisting of select- and a unique number for the elements. If it does have an ID, it will use its ID as the prefix. The ID for the various elements generated by the selectmenu widget is then constructed as follows:
<prefix>-button
<prefix>-listbox
This id is only assigned to an element when the selectmenu widget is constructed with the option nativeMenu set to false.
Since the menu is implemented as a popup it will assign IDs to its generated elements. See the popup widget's id generation for details.
<prefix>-menu
This id is only assigned to an element when the selectmenu widget is constructed with the option nativeMenu set to false.
For example, creating a non-native selectmenu with
<select id="choose-city" data-native-menu="false">
<option>Caracas</option>
<option>Warszawa</option>
<option>Yekaterinburg</option>
<option>Pretoria</option>
</select>
will result in the following markup:
<div class="ui-select">
<a id="choose-city-button" href="#" role="button" aria-haspopup="true" class="ui-btn ui-icon-carat-d ui-btn-icon-right ui-corner-all ui-shadow" data-rel="popup">
<span>Caracas</span>
</a>
<select id="choose-city" data-native-menu="false" tabindex="-1">
<option>Caracas</option>
<option>Warszawa</option>
<option>Yekaterinburg</option>
<option>Pretoria</option>
</select>
<div id="choose-city-listbox-placeholder" style="display: hidden;"></div>
</div>
<div id="choose-city-listbox-screen" class="ui-popup-screen ui-screen-hidden ui-overlay-inherit"></div>
<div id="choose-city-listbox-popup" class="ui-popup-container ui-popup-hidden ui-popup-truncate">
<div id="choose-city-listbox" class="ui-selectmenu ui-popup ui-body-inherit ui-overlay-shadow ui-corner-all">
<div class="ui-header" ui-bar-inherit ui-screen-hidden">
<h1 class="ui-title"></h1>
</div>
<ul id="choose-city-menu" class="ui-selectmenu-list ui-listview" role="listbox" aria-labelledby="choose-city-button">
<li data-option-index="0" data-icon="false" class="ui-first-child" role="option" aria-selected="true">
<a href="#" tabindex="-1" class="ui-btn ui-btn-active">Caracas</a>
</li>
<li data-option-index="0" data-icon="false" role="option" aria-selected="false">
<a href="#" tabindex="-1" class="ui-btn ui-btn-active">Warszawa</a>
</li>
<li data-option-index="0" data-icon="false" role="option" aria-selected="false">
<a href="#" tabindex="-1" class="ui-btn ui-btn-active">Yekaterinburg</a>
</li>
<li data-option-index="0" data-icon="false" class="ui-last-child" role="option" aria-selected="false">
<a href="#" tabindex="-1" class="ui-btn ui-btn-active">Pretoria</a>
</li>
</ul>
</div>
</div>
optionName.optionName.This is used to update the custom select to reflect the native select element's value. If the number of options in the select are different than the number of items in the custom menu, it'll rebuild the custom menu.
This is used to update the custom select to reflect the native select element's value. If the number of options in the select are different than the number of items in the custom menu, it'll rebuild the custom menu. If you pass a true argument you can force the rebuild to happen.
To add a slider widget to your page, use a standard input with the type="range" attribute. The input's value is used to configure the starting position of the handle and the value is populated in the text input. Specify min and max attribute values to set the slider's range. If you want to constrain input to specific increments, add the step attribute. Set the value attribute to define the initial value. The framework will parse these attributes to configure the slider widget.
As you drag the slider's handle, the framework will update the native input's value (and vice-versa) so they are always in sync; this ensures that the value is submitted with the form.
Set the for attribute of the label to match the id of the input so they are semantically associated. It's possible to accessibly hide the label if it's not desired in the page layout, but we require that it is present in the markup for semantic and accessibility reasons.
The framework will find all input elements with a type="range" and automatically enhance them into a slider with an accompanying input without any need to apply a data-role attribute. To prevent the automatic enhancement of this input into a slider, add data-role="none" attribute to the input.
In this example, the acceptable range is 0-100.
<label for="slider-1">Input slider:</label>
<input type="range" name="slider-1" id="slider-1" value="60" min="0" max="100">
The default slider with these settings is displayed like this:
The slider widget uses the jQuery Mobile CSS framework to style its look and feel. If slider specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-slider: The outermost container for slider.
ui-slider-popup: Tooltip popup element in case data-popup-enabled is true
ui-slider-input: Input element of slider
ui-slider-track: Slider's track
ui-slider-handle: Handle of slider's track
To force the slider to snap to a specific increment, add the step attribute to the input. By default, the step is 1, but in this example, the step is 10 and the maximum value is 500.
In this example, the acceptable range is 0-100.
<label for="slider-1">Input slider:</label>
<input type="range" name="slider-1" id="slider-1" value="60" min="0" max="100" step="10">
This will produce an input that snaps to increments of 50. If a value is added to the input that isn't valid with the step increment, the value will be reset on blur to the closest step.
To have a highlight fill on the track up to the slider handle position, add the data-highlight="true" attribute to the input. The fill uses active state swatch.
<label for="slider-fill">Input slider:</label>
<input type="range" name="slider-fill" id="slider-fill" value="60" min="0" max="100" data-highlight="true">
For a more compact version that is useful in toolbars and tight spaces, add the data-mini="true" attribute to the element to create a mini version.
<label for="slider-mini">Input slider:</label>
<input type="range" name="slider-mini" id="slider-mini" value="25" min="0" max="100" data-highlight="true" data-mini="true">
This will produce a slider and its corresponding input that are not as tall as the standard version. The input also has a smaller text size.
Optionally wrap the slider markup in a container with class ui-field-contain to help visually group it in a longer form. In this example, the step attribute is omitted to allow any whole number value to be selected.
Note: The data- attribute data-role="fieldcontain" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Add class ui-field-contain instead.
<div class="ui-field-contain">
<label for="slider-2">Input slider:</label>
<input type="range" name="slider-2" id="slider-2" value="25" min="0" max="100">
</div>
The slider is now displayed like this:
Sliders also respond to key commands. Right Arrow, Up Arrow and Page Up keys increase the value; Left Arrow, Down Arrow and Page Down keys decrease it. To move the slider to its minimum or maximum value, use the Home or End key, respectively.
This plugin will auto initialize on any page that contains a text input with the type="range" attribute. However, if needed you can directly call the slider plugin on any selector, just like any jQuery plugin:
$( "input" ).slider();
To set the theme swatch for the slider, add a data-theme attribute to the input which will apply the theme to both the input, handle and track. The track swatch can be set separately by adding the data-track-theme attribute to apply the down state version of the selected button swatch.
<div class="ui-field-contain">
<label for="slider-3">Input slider:</label>
<input type="range" name="slider-3" id="slider-3" value="25" min="0" max="100" data-theme="b" data-track-theme="a">
</div>
This will produce a themed slider:
Note: The flip toggle switch feature is deprecated as of jQuery Mobile 1.4.0. Use the Flipswitch widget instead.
A binary "flip" switch is a common UI element on mobile devices that is used for binary on/off or true/false data input. You can either drag the flip handle like a slider or tap one side of the switch.
To create a flip toggle, start with a select with two options. The first option will be styled as the "off" state switch and the second will be styled as the "on" state so write your options accordingly.
Set the for attribute of the label to match the id of the input so they are semantically associated. It's possible to accessibly hide the label if it's not desired in the page layout, but we require that it is present in the markup for semantic and accessibility reasons.
<label for="flip-1">Flip switch:</label>
<select name="flip-1" id="flip-1" data-role="slider">
<option value="off">Off</option>
<option value="on">On</option>
</select>
This will produce a basic flip toggle switch input. The default styles set the width of the switch to 100% of the parent container and stack the label on a separate line.
The control is proportionally scaled, so to use longer labels one can just add a line of CSS setting the switch to the desired width. For example, given the following markup:
<div class="containing-element">
<label for="flip-min">Flip switch:</label>
<select name="flip-min" id="flip-min" data-role="slider">
<option value="off">Switch Off</option>
<option value="on">Switch On</option>
</select>
</div>
.containing-element .ui-slider-switch { width: 9em } will produce:
As some default styles hinge on fieldcontains, note that you may have to ensure that custom styles apply to switches within fieldcontains by using .ui-field-contain div.ui-slider-switch { width: […]; }.
For a more compact version that is useful in toolbars and tight spaces, add the data-mini="true" attribute to the element to create a mini version.
<label for="flip-mini">Flip switch:</label>
<select name="flip-mini" id="flip-mini" data-role="slider" data-mini="true">
<option value="off">Off</option>
<option value="on">On</option>
</select>
This will produce a flip switch that is not as tall as the standard version and has a smaller text size.
Optionally wrap the switch markup in a container with class ui-field-contain to help visually group it in a longer form. In this example, the step attribute is omitted to allow any whole number value to be selected.
Note: The data- attribute data-role="fieldcontain" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Add class ui-field-contain instead.
<div class="ui-field-contain">
<label for="flip-2">Flip switch:</label>
<select name="flip-2" id="flip-2" data-role="slider" data-mini="true">
<option value="off">Off</option>
<option value="on">On</option>
</select>
</div>
The flip toggle switch is now displayed like this:
Like all form elements, this widget will automatically inherit the theme from its parent container. To choose a specific theme color swatch, specify the data-theme attribute on the select and specify a swatch letter.
<div class="ui-field-contain">
<label for="flip-3">Flip switch:</label>
<select name="flip-3" id="flip-3" data-role="slider" data-theme="b">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
This results in a switch with the swatch "b" colors for the handle. Note that the lefthand "on" state gets the active state color.
Here is a swatch "a" variation:
It is also possible to theme the track of the flip switch by adding the data-track-theme attribute and specifying the chosen swatch letter on the select.
Here's an example of a flip switch with the swatch "a" applied to the track and swatch "c" applied to the handle:
<div class="ui-field-contain">
<label for="flip-5">Flip switch:</label>
<select name="flip-5" id="flip-5" data-role="slider" data-theme="a" data-track-theme="b">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
This plugin will auto initialize on any page that contains a text input with the type="slider" attribute. However, if needed you can directly call the slider plugin on any selector, just like any jQuery plugin:
$( "input" ).slider();
Like all form elements, this widget will automatically inherit the theme from its parent container. To choose a specific theme color swatch, specify the data-theme attribute on the select and specify a swatch letter.
<div class="ui-field-contain">
<label for="flip-3">Flip switch:</label>
<select name="flip-3" id="flip-3" data-role="slider" data-theme="a">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
This results in a switch with the swatch "a" colors for the handle. Note that the lefthand "on" state gets the active state color.
It is also possible to theme the track of the flip switch by adding the data-track-theme attribute and specifying the chosen swatch letter on the select.
Here's an example of a flip switch with the swatch "a" applied to the track and swatch "c" applied to the handle:
<div class="ui-field-contain">
<label for="flip-5">Flip switch:</label>
<select name="flip-5" id="flip-5" data-role="slider" data-theme="a" data-track-theme="b">
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
</div>
optionName.optionName.If you manipulate a slider via JavaScript, you must call the refresh method on it to update the visual styling.
Triggered when a horizontal drag of 30px or more (and less than 30px vertically) occurs within 1 second duration but these can be configured:
$.event.special.swipe.scrollSupressionThreshold (default: 10px) – More than this horizontal displacement, and we will suppress scrolling.$.event.special.swipe.durationThreshold (default: 1000ms) – More time than this, and it isn't a swipe.$.event.special.swipe.horizontalDistanceThreshold (default: 30px) – Swipe horizontal displacement must be more than this.$.event.special.swipe.verticalDistanceThreshold (default: 30px) – Swipe vertical displacement must be less than this.The swipe event can also be extend to add your own logic or functionality. The following methods can be extended:
$.event.special.swipe.start Default:
function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event;
return {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ],
origin: $( event.target )
};
}
This method recieves a touchstart event and returns an object of data about the starting location.
$.event.special.swipe.stop Default:
function( event ) {
var data = event.originalEvent.touches ?
event.originalEvent.touches[ 0 ] : event;
return {
time: ( new Date() ).getTime(),
coords: [ data.pageX, data.pageY ]
};
}
This method recieves a touchend event and returns an object of data about the ending location.
$.event.special.swipe.handleSwipe Default:
function( start, stop ) {
if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
start.origin.trigger( "swipe" )
.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
}
}
This method recieves the start and stop objects and handles the logic for and triggering for the swipe events.
$(function(){
// Bind the swipeHandler callback function to the swipe event on div.box
$( "div.box" ).on( "swipe", swipeHandler );
// Callback function references the event target and adds the 'swipe' class to it
function swipeHandler( event ){
$( event.target ).addClass( "swipe" );
}
});
Triggered when a horizontal drag of 30px or more (and less than 30px vertically) occurs within 1 second duration in the left direction. See the swipe event entry for more detailed information on the swipe event.
$(function(){
// Bind the swipeleftHandler callback function to the swipe event on div.box
$( "div.box" ).on( "swipeleft", swipeleftHandler );
// Callback function references the event target and adds the 'swipeleft' class to it
function swipeleftHandler( event ){
$( event.target ).addClass( "swipeleft" );
}
});
Triggered when a horizontal drag of 30px or more (and less than 30px vertically) occurs within 1 second duration in the right direction. See the swipe event entry for more detailed information on the swipe event.
$(function(){
// Bind the swiperightHandler callback function to the swipe event on div.box
$( "div.box" ).on( "swiperight", swiperightHandler );
// Callback function references the event target and adds the 'swiperight' class to it
function swiperightHandler( event ){
$( event.target ).addClass( "swiperight" );
}
});
This table mode automatically hides less important columns at narrower widths and surfaces a button to open a menu that allows the user to choose what columns they want to see. In this mode, the author attempts to define which columns are most important to show across various widths by assigning a priority to each column.
A user may choose to check as many columns as they want by tapping the "Columns..." button to open the column chooser popup. The popup contains a dynamically generated list of columns based on the table markup that can be checked and unchecked to adjust the visible columns.
The column chooser mode requires a table element with two attributes: data-role="table" and data-mode="columntoggle". An ID attribute is also required on the table to associate it with the column chooser popup menu.
<table data-role="table" data-mode="columntoggle" id="my-table">
The plugin automates a few key things: it injects the column chooser button, and generates the popup with check list of columns that can be hidden or shown by the user. The list of columns in the chooser menu is populated by parsing the values (or abbr title) of the first row of header (TH) elements. Only headers that have a data-priority attribute are included in the column chooser; headers without this attribute won't made available in the chooser to allow developers to identify critical columns that shouldn't be hidden. If columns are hidden via responsive media queries, these will be unchecked in the chooser to reflect the current column visibility.
The automatic column hiding behavior is accomplished by CSS media queries that hide or show columns based on priority levels at various screen widths. Since each site will have different content and column configurations, we provide a simple media query block that you can copy, paste and customize for each project. This is explained in detail below.
The priorities assigned to headers and media queries used to hide columns act as a sensible default for showing the most important columns that will fit on a device. The column chooser menu gives users the ability to override these defaults and choose which columns they want to see. These user preferences take precedence over the priority mappings so if a column is manually checked, it will remain visible across all screen widths until the page is refreshed.
Because of the flexibility this plugin provides, it's possible for users to introduce horizontal scrolling if the data in each column is long or if many columns are selected to be shown on a smaller screen.
The table works by hiding and showing columns based on two inputs: available screen width or by the user checking and unchecking which columns to display in a column picker popup. Add data-priority attributes to each of the table headers of columns you want to responsively display and assign a priority (1 = highest, 6 = lowest). Any table header given a priority will be available in the column picker menu.
To make a column persistent so it's not available for hiding, omit the data-priority attribute. This will make the column visible at all widths and won't be available in the column chooser menu.
<th>I'm critical and can't be removed</th>
<th data-priority="1">I'm very important</th>
<th data-priority="3">I'm somewhat</th>
<th data-priority="5">I'm less important</th>
Behind the scenes, the plugin will apply classes to each cell that map to the priority set in the data attribute on the header. For example, if a table heading has a data-priority="3" attribute, every cell in that column will assigned a ui-table-priority-3 class once enhanced. These classes are then used in media queries to hide and show columns based on screen width (see below).
<td class="ui-table-priority-3">97%</td>
You may use any priority naming convention and assign as many (or few) levels of priority for the columns. The plugin simply generates class names based on the values in the data-priority attribute so even though we default to using a numeric system of 1-6, any naming convention is possible.
For example, if a priority of data-priority="critical" is added to the heading, a class of ui-table-priority-critial will be applied to each cell in that column. If a priority is assigned, the column will be made available for the toggling in the column menu and adds the classes to each cell, the rest of the styling and media query creation is up to you write in your custom stylesheet.
It is important to note that you are required to wrap your table headers in a <thead> ... </thead> block, and the table body in a <tbody> ... </tbody> block, as shown in the full demo Example.
The styles for the all priority columns (1-6) start as display:none in the structure stylesheet since we're taking a mobile-first approach to our styles. This means that only columns that should be persistent are visible in the styles to start.
The framework does not automatically include the the media queries to progressively display columns at wider widths. We do this to make it easier for developers to customize the media query widths for each priority level.
Media queries add the responsive behavior to show and hide columns by priority. Each media query is written using min-width widths so they build on top of each other. The widths are set in ems so they respond to font size changes. To calculate a pixel withs in em's, divide the target width by 16 (pixels) - it's that easy.
Inside each media query, we override the display:none style properties set on all the priority columns in the basic styles to display:table-cell so they become visible again and act as a table.
To customize the breakpoints, copy the following style block into your custom style overrides and adjust the min-width media query values for each priority level to specify where various priority columns should appear.
In the example styles below for a my-custom-class class on the table, the priority 1 columns are shown first, at widths above 20em (320px), then priority 2 kicks in above 30em (480px) and so on up to wide desktop widths with priority 6. Feel free to change these breakpoints in your stylesheet and choose how many priority levels you'd like to use.
/* Show priority 1 at 320px (20em x 16px) */
@media screen and (min-width: 20em) {
.my-custom-class th.ui-table-priority-1,
.my-custom-class td.ui-table-priority-1 {
display: table-cell;
}
}
/* Show priority 2 at 480px (30em x 16px) */
@media screen and (min-width: 30em) {
.my-custom-class th.ui-table-priority-2,
.my-custom-class td.ui-table-priority-2 {
display: table-cell;
}
}
...more breakpoints...
Due to CSS specificity, you will also need to include the class definitions for the hidden and visible states after the custom breakpoints in your custom stylesheet so be sure to include these as well:
/* Manually hidden */
.my-custom-class th.ui-table-cell-hidden,
.my-custom-class td.ui-table-cell-hidden {
display: none;
}
/* Manually shown */
.my-custom-class th.ui-table-cell-visible,
.my-custom-class td.ui-table-cell-visible {
display: table-cell;
}
Even though we strongly encourage you to write custom breakpoints yourself, the framework includes a set of pre-configured breakpoints for each of the six priority levels that you can use if they happen work well for your content.
These breakpoints can applied by adding a class="ui-responsive" to the table element. Here is an example of a table with this class added:
<table data-role="table" class="ui-responsive" data-mode="columntoggle" id="my-table">
The six preset breakpoints classes included in the column toggle stylesheet use regular increments of 10em (160 pixels). Here is a summary of the breakpoints assigned to each priority in the preset styles:
data-priority="1"data-priority="2"data-priority="3"data-priority="4"data-priority="5"data-priority="6"If these preset breakpoints don't work for your content and layout needs, we recommend that you create custom breakpoints to fine tune the styles.
When the column chooser menu opens, the column checkboxes will be checked or unchecked based on the visibility of each column based on the media queries so it accurately reflects what is being seen. These media queries to hide or show columns act as sensible defaults for what columns should be shown based on the developer's understanding of the column importance and data values. The chooser menu allows the user to have control of the table presentation so this takes precedence over the default display.
If an unchecked column checkbox is checked by the user, they now take control of the column. Until the page is refreshed, the visibility of that column will now always be visible, even if the screen is re-sized. Behind the scenes, a class of ui-table-cell-visible is added to all the cells in that column to ensure they override any visibility set via media queries.
The same idea applies when a column is unchecked: from then on, the column won't be seen at any width because the class of ui-table-cell-hidden is added to each of the cells in that column.
The column chooser popup is opened via a button that is generated by the framework. The button's text is "Columns..." by default but can be set by adding the data-column-btn-text attribute to the table to the text string you want in the button. The button will inherit the theme from the content area, just like all buttons, but the theme can be set manually by adding the data-column-btn-theme attribute to any swatch letter in your theme.
This button is injected directly before the table element and has basic styles to align it to the right but you may want to further customize the appearance of this button. To style all these buttons across your site, key off the ui-table-columntoggle-btn structural class on this link.
To target styles against only a specific button, use the unique href value that is generated to target a specific column chooser button. For example, a table with an ID of movie-table will generate a popup with an ID of movie-table-popup so a CSS selector of a[href="#movie-table-popup"] will target only the column popup button for this specific table.
The theme for the column chooser popup can be set by adding the data-column-popup-theme attribute to the table and specifying any swatch letter in your theme. For custom styles or scripting, all the column chooser popups can be targeted by using the ui-table-columntoggle-popup structural class added to these popups. To customize a single popup, use the generated ID based on the table ID that added to each specific popup (such as #movie-table-popup) to target a specific popup.
It's fairly common to need to logically group multiple columns together under a heading group for financial or scientific data. The framework can support the most simple version of this by allowing for two rows of table headers (TH), with the first row containing simple colspan attributes to group the columns below. In this configuration, the framework will parse the first row only for the priority and expose these heading groups as the options in the column chooser popup. In this configuration, the second heading will not be exposed as columns that can be hidden or shown independently of the groupings in the chooser.
You can improve the load time of your page by providing the markup that the table-columntoggle widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the table-columntoggle widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The columntoggle table places an anchor before the table that invokes a popup listing the columns available for showing/hiding. The ID of the popup and thus the href of the anchor should be the ID of the table suffixed by the string -popup. You may separately pre-enhance the popup widget, or you may allow autoinitialization to enhance it.
The popup widget must contain a single controlgroup widget which in turn contains all the checkboxes representing the columns of the table.
In the example below the parameter data-column-btn-theme="b" is added to the table explicitly to indicate that the theme applied to the "Columns..." button is not the default (null).
<div data-role="popup" id="table-column-toggle-popup" class="ui-table-columntoggle-popup">
<fieldset data-role="controlgroup">
<label>Rank<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
<label>Year<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
<label>Rotten Tomato Rating<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
<label>Reviews<input type="checkbox" checked data-cacheval="false" locked="true"></input></label>
</fieldset>
</div>
<a href="#table-column-toggle-popup" class="ui-table-columntoggle-btn ui-btn ui-btn-b ui-corner-all ui-shadow ui-mini" data-rel="popup">Columns...</a>
<table data-role="table" id="table-column-toggle" data-mode="columntoggle" data-enhanced="true" class="ui-table ui-table-columntoggle" data-column-btn-theme="b">
<thead>
<tr>
<th data-priority="2" data-colstart="1" class="ui-table-priority-2 ui-table-cell-visible">Rank</th>
<th data-colstart="2">Movie Title</th>
<th data-priority="3" data-colstart="3" class="ui-table-priority-3 ui-table-cell-visible">Year</th>
<th data-priority="1" data-colstart="4" class="ui-table-priority-1 ui-table-cell-visible"><abbr title="Rotten Tomato Rating">Rating</abbr></th>
<th data-priority="5" data-colstart="5" class="ui-table-priority-5 ui-table-cell-visible">Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<th class="ui-table-priority-2 ui-table-cell-visible">1</th>
<td><a href="http://en.wikipedia.org/wiki/Citizen_Kane" data-rel="external">Citizen Kane</a></td>
<td class="ui-table-priority-3 ui-table-cell-visible">1941</td>
<td class="ui-table-priority-1 ui-table-cell-visible">100%</td>
<td class="ui-table-priority-5 ui-table-cell-visible">74</td>
</tr>
<tr>
<th class="ui-table-priority-2 ui-table-cell-visible">2</th>
<td><a href="http://en.wikipedia.org/wiki/Casablanca_(film)" data-rel="external">Casablanca</a></td>
<td class="ui-table-priority-3 ui-table-cell-visible">1942</td>
<td class="ui-table-priority-1 ui-table-cell-visible">97%</td>
<td class="ui-table-priority-5 ui-table-cell-visible">64</td>
</tr>
</tbody>
</table>
The reflow table mode works by collapsing the table columns into a stacked presentation that looks like blocks of label/data pairs for each row. Since the HTML source order of a table prohibits styling a table to look like this, the plugin dynamically adds a bit of markup to make the display work (without affecting accessibility). Here is a demo of a basic table using reflow mode:
The reflow responsive table mode is the simplest in terms of markup requirements because it only requires a table with a data-role="table" on the table element. There is no need to set the data-mode attribute since reflow is the default.
<table data-role="table" id="my-table">
The plugin works by parsing the values (or abbr title) of the first row of header (th) elements found in the table. For example, in the table above, the third table header is parsed to grab the contents ("Year"):
<th>Year</th>
The script then appends an element with the table header text before the contents of every cell in that column. For example, for every table cell in the year column:
<td>1941</td>
An element is added before the text of each cell with a class of ui-table-cell-label:
<td><b class="ui-table-cell-label">Year</b>1941</td>
With our mobile-first approach, the base styles for a reflow table stacks each row and presents each cell in the label/data style format. This is done by hiding the table header rows, making each table cell display:block so they are stacked. The the label element injected into each cell is styled as display:inline-block with a min-width:30% rule to place the labels on the same line as the content at a consistent width to form a two column presentation.
It is important to note that you are required to wrap your table headers in a <thead> ... </thead> block, and the table body in a <tbody> ... </tbody> block, as shown in the full demo Example.
By default, a table with reflow mode will display the stacked presentation style on all screen widths. The styles to make the table responsive are added by applying a media query with rules to switch to the tabular style presentation above a specific screen width.
This is done by wrapping a few simple CSS rules in and a media query that only applies the rules above a certain width breakpoint. The styles make the table header rows visible, display the cells in a tabular format, and hide the generated label elements within each. Here is an example media query that swaps the presentation at 40em (640 pixels):
@media ( min-width: 40em ) {
/* Show the table header rows and set all cells to display: table-cell */
.my-custom-breakpoint td,
.my-custom-breakpoint th,
.my-custom-breakpoint tbody th,
.my-custom-breakpoint tbody td,
.my-custom-breakpoint thead td,
.my-custom-breakpoint thead th {
display: table-cell;
margin: 0;
}
/* Hide the labels in each cell */
.my-custom-breakpoint td .ui-table-cell-label,
.my-custom-breakpoint th .ui-table-cell-label {
display: none;
}
}
It's best to use a class on the table to apply the breakpoint. Add these rules to your custom stylesheet that is included in the head of the page. We recommend creating a set of custom breakpoint classes that can be used to apply standard table breakpoints in your project.
In the example above, we're assuming there is a class of my-custom-breakpoint added to the table to apply the breakpoint. Each of the rules in the custom media query are scoped against that table class to target only tables that have the my-custom-breakpoint class.
In order for this technique to work, a browser must support media queries and the ability to style table cells as block-level elements. In testing, most popular desktop and mobile browsers meet these criteria, but older versions of Internet Explorer (8 and older) fall back to a normal table presentation. IE 9 can support this technique but there are a few additional styles needed so we recommend applying these in a max-width media query to only apply them below the table presentation because they are hard to negate.
The goal is to determine the minimum width at which the entire table will fit comfortably within the screen. Find this width by populating a table with realistic sample data, then adjust the browser window until the table completely fits and has a bit of extra space to account for rendering differences across devices. This is the natural place to set the breakpoint that switches between the stacked and tabular presentation modes.
The breakpoint width is highly dependent on the number of columns in the table and content within each cell. On some sites, this may be as low as 30em (480px) and on others, it could be as wide as 100em (1,600px). There is no way for the framework to decide on a "standard breakpoint" that will work for everyone — that's why there isn't a breakpoint built into the table by default.
We recommend writing media query widths are in em's so they respond to font size changes. To convert a pixel width into em's, divide the target width by 16 (pixels). Use this value for the min-width value in the media query above.
Even though we strongly encourage you to write custom breakpoints yourself, the framework includes a single pre-configured breakpoint that targets the stacked style to smaller phones and swaps to a tabular prsentation on larger phones, tablet and desktop devices. To use this preset breakpoint, add the ui-responsive class to the table to convert from the stacked presentation to a tabular presentation at 560px (35em). If this breakpoint doesn't work for your content, we encourage you to write a custom breakpoint as descibed above.
<table data-role="table" class="ui-responsive">
It's fairly common to need to logically group multiple columns together under a heading group for financial or scientific data. The framework can support the most simple version of this by allowing for two rows of table headers (TH), with the first row containing simple colspan attributes to group the columns below. In this configuration, the framework will add a class to the label of the first cell in each group to allow you to style these differently and provide aditional visual hierarchy.
One of the biggest challenges in responsive web design (RWD) is presenting tabular data. Large tables with lots of columns don't fit on smaller screens and there isn't a simple way to re-format the table content with CSS and media queries for an acceptable presentation. To address this, the framework offers two different options for presenting tables responsively. Each has benefits and tradeoffs, the right choice will depend on the data being presented.
Reflow mode - Re-formats the table columns at narrow widths so each row of data is presented as a formatted block of label/data pairs. This is ideal for tables with product or contact information with more complex or lengthy data formatting that doesn't need comparison across rows of data.
Column toggle mode - Selectively hides columns at narrower widths as a sensible default but also offers a menu to let users manually control which columns they want to see. This mode is better for financial data tables that have compact values and need to maintain comparisons across columns and rows of data. It can also be used for building things like product comparison tables.
The responsive table feature is built with a core table plugin (table.js) that initializes when the data-role="table" attribute is added to the markup. This plugin is very lightweight and adds ui-table class, parses the table headers and generates information on the columns of data, and fires a tablecreate event. Both the table modes, reflow and column toggle, are written as extensions to the table widget that hook in via the create event to add the additional behaviors that make the tables responsive. Reflow is the default mode so if the extension is present, it will be applied automatically if the data-role="table" attribute is on the table.
If only one mode is used on a project, the download builder tool can be used to package only the table plugin and the single extension to save code weight.
Here is the basic table markup you should use for both table modes:
<table data-role="table" id="my-table" data-mode="reflow">
<thead>
<tr>
<th>Rank</th>
<th>Movie Title</th>
<th>Year</th>
<th><abbr title="Rotten Tomato Rating">Rating</abbr></th>
<th>Reviews</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td><a href="foo.com" data-rel="external">Citizen Kane</a></td>
<td>1941</td>
<td>100%</td>
<td>74</td>
</tr>
</tbody>
</table>
Both table modes start with standard HTML table markup but there are some specific guidelines you must follow for the responsive table to work correctly:
rowspan or colspan in your tables, these aren't supported except for grouped headers (see below)thead and tbody elements are optional but provide improved semanticsID to the table (required for the column toggle mode)data-role="table" to apply the responsive table pluginreflow, add data-mode="columntoggle" change modesTH instead of TD tagsTH with a abbr element and set the title. This string will be used in place.The responsive table plugin is as minimally styled as possible to give you a clean slate for your designs. The plugin focuses primarily on the difficult scripting elements: generating the labels for the reflow table and creating the button and column chooser popup. Out of the box, the table just has a few basic style rules to add a bit of padding and set the vertical alignment of cells to be top left for visual consistency.
The table will adapt to whatever content block it sits on, but there isn't an explicit theming attribute for this widget. We did this because it's simple enough to add theme classes like ui-body-a to individual cells if a more heavily themed look is wanted.
The theme CSS contains a preset row strokes and alternating row stripes style which can be applied by adding table-stroke or table-stripe class to the table element.
table-stroke and table-stripe classes are deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. The demos contain an example how to apply these styles with custom CSS.
The jQuery Mobile tap event triggers after a quick, complete touch event that occurs on a single target object. It is the gesture equivalent of a standard click event that is triggered on the release state of the touch gesture.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .tap() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
Tap makes use of vclick and therefore should be used with caution on touch devices. See the vclick API documentation for more details.
$(function(){
$( "div.box" ).bind( "tap", tapHandler );
function tapHandler( event ){
$( event.target ).addClass( "tap" );
}
});
The jQuery Mobile taphold event triggers after a sustained, complete touch event (also known as a long press).
$.event.special.tap.tapholdThreshold (default: 750) - This value dictates how long the user must hold their tap before the taphold event is fired on the target element.
$.event.special.tap.emitTapOnTaphold (default: true) - This value dictates whether a tap event will be emitted along with the taphold event.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .taphold() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
$(function(){
$( "div.box" ).bind( "taphold", tapholdHandler );
function tapholdHandler( event ){
$( event.target ).addClass( "taphold" );
}
});
Text inputs and textareas are coded with standard HTML elements, then enhanced by jQuery Mobile to make them more attractive and useable on a mobile device.
To collect standard alphanumeric text, use an input with a type="text" attribute. Set the for attribute of the label to match the id of the input so they are semantically associated. It's possible to accessibly hide the label if it's not desired in the page layout, but we require that it is present in the markup for semantic and accessibility reasons.
The textinput widget uses the jQuery Mobile CSS framework to style its look and feel. If textinput specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-textinput: The outermost container for textinput. ui-textinput-search or ui-textinput-text classes will be applied if textinput has type='search' or not accordingly. ui-textinput-clear-button class will be applied when clearBtn option is true. ui-textinput-autogrow class will be applied when autogrow option is true.
ui-textinput-search-icon: Search icon's class when type of textinput is search
<label for="basic">Text Input:</label>
<input type="text" name="name" id="basic" value="">
This will produce a basic text input. The default styles set the width of the input to 100% of the parent container and stack the label on a separate line.
For a more compact version that is useful in toolbars and tight spaces, add the data-mini="true" attribute to the element to create a mini version.
<label for="basic">Text Input:</label>
<input type="text" name="name" id="basic" value="" data-mini="true">
This will produce an input that is not as tall as the standard version and has a smaller text size.
The clearButton extension provides the clearBtn option.
To add a clear button to any input (like the search input), add the data-clear-btn="true" attribute. The text for this clear button can be customized via the data-clear-btn-text="clear input" attribute. Search buttons have the clear button by default and cannot be controlled by this option. Note that this is available for all the input types below except for those coded via textarea elements.
<label for="clear-demo">Text Input:</label>
<input type="text" name="clear" id="clear-demo" value="" data-clear-btn="true">
This markup creates a text input with a clear button that becomes visible as soon as a character has been entered.
Optionally wrap the text input in a container with class ui-field-contain to help visually group it in a longer form.
Note: The data- attribute data-role="fieldcontain" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Add class ui-field-contain instead.
<div class="ui-field-contain">
<label for="name">Text Input:</label>
<input type="text" name="name" id="name" value="">
</div>
The text input is now displayed like this:
In jQuery Mobile, you can use existing and new HTML5 input types such as password, email, tel, number, and more. Some type values are rendered differently across browsers. For example, Chrome renders the range input as a slider. jQuery Mobile standardizes the appearance of range and search by dynamically changing their type to text. You can configure which input types are degraded to text with the page plugin's options.
One major advantage of using these more specific input types if that on mobile devices, specialized keyboards that speed data entry are offered in place of the standard text keyboard. Try the following inputs on a mobile device to see which display custom keyboards on various platforms.
jQuery Mobile-styled textinput widgets can be placed outside jQuery Mobile pages. To do so, specify their input type as type="text", add the attribute data-type="search", and manually call the textinput plugin on the element.
The markup:
<input id="the-search-input" type="text" data-type="search">
The script:
$( function() {
$( "#the-search-input" ).textinput();
});
For multi-line text inputs, use a textarea element. The autogrow extension provides functionality for auto-growing the height of the textarea to avoid the need for an internal scrollbar.
Set the for attribute of the label to match the id of the textarea so they are semantically associated, and wrap them in a div with class ui-field-contain to group them.
Note: The data- attribute data-role="fieldcontain" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Add class ui-field-contain instead.
<label for="textarea-a">Textarea:</label>
<textarea name="textarea" id="textarea-a">
I'm a basic textarea. If this is pre-populated with content, the height will be automatically adjusted to fit without needing to scroll. That is a pretty handy usability feature.
</textarea>
This will produce a basic textarea with the width set to 100% of the parent container and the label stacked on a separate line. The textarea will grow to fit new lines as you type:
<div class="ui-field-contain">
<label for="textarea">Textarea:</label>
<textarea name="textarea" id="textarea"></textarea>
</div>
The textarea is displayed like this and will grow to fit new lines as you type:
This plugin will auto initialize on any page that contains a textarea or any of the text input types listed above without any need for a data-role attribute in the markup. However, if needed, you can directly call the textinput plugin on any selector, just like any jQuery plugin:
$( "input" ).textinput();
The location of the map of input type degradations in the page plugin is deprecated as of 1.4.0. As of 1.5.0 the input type degradation functionality will be implemented by the degradeInputs module.
jQuery Mobile degrades several HTML5 input types back to type=text or type=number after adding enhanced controls. For example, inputs with a type of range are enhanced with a custom slider control, and their type is set to number to offer a usable form input alongside that slider. Inputs with a type of search are degraded back to type=text after we add our own themeable search input styling.
The degradeInputs module contains a list of input types that are set to either true which means they'll degrade to type=text, false which means they'll be left alone, or a string such as "number", which means they'll be converted to that type (such as the case of type=range).
You can configure which types are changed via $.mobile.degradeInputs, which has properties: color, date, datetime, "datetime-local", email, month, number, range, search, tel, time, url, and week. Be sure to configure this inside an event handler bound to the mobileinit event, so that it applies to the first page as well as subsequent pages that are loaded.
Search inputs are a new HTML type styled with pill-shaped corners and an "x" icon to clear the field once you start typing. Start with an input with a type="search" attribute in your markup.
Set the for attribute of the label to match the id of the input so they are semantically associated. It's possible to accessibly hide the label if it's not desired in the page layout, but we require that it is present in the markup for semantic and accessibility reasons.
<label for="search-basic">Search Input:</label>
<input type="search" name="search" id="search-basic" value="">
This will produce a basic search input. The default styles set the width of the input to 100% of the parent container and stack the label on a separate line.
For a more compact version that is useful in toolbars and tight spaces, add the data-mini="true" attribute to the element to create a mini version.
<label for="search-mini">Search Input:</label>
<input type="search" name="search-mini" id="search-mini" value="" data-mini="true">
This will produce a search input that is not as tall as the standard version and has a smaller text size.
Optionally wrap the search input in a container with tlass ui-field-contain to help visually group it in a longer form.
Note: The data- attribute data-role="fieldcontain" is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Add class ui-field-contain instead.
<div class="ui-field-contain">
<label for="search-2">Search Input:</label>
<input type="search" name="search-2" id="search-2" value="">
</div>
The search input is now displayed like this:
The data-theme attribute can be added to the search input to set the theme to any swatch letter.
The text for the button used to clear the search input of text can be configured for all search inputs by binding to the mobileinit event and setting the
$.mobile.textinput.prototype.options.clearBtnText property to a string of your choosing.
This option is provided by the clearButton extension.
This plugin will auto-initialize on any page that contains a text input with the type="search" attribute without any need for a data-role attribute in the markup. However, if needed, you can directly call the textinput plugin on a selector, just like any jQuery plugin:
$( ".mySearchInput" ).textinput();
You can improve the load time of your page by providing the markup that the textinput widget would normally create during its initialization.
By providing this markup yourself, and by indicating that you have done so by setting the attribute data-enhanced="true", you instruct the textinput widget to skip these DOM manipulations during instantiation and to assume that the required DOM structure is already present.
When you provide such pre-rendered markup you must also set all the classes that the framework would normally set, and you must also set all data attributes whose values differ from the default to indicate that the pre-rendered markup reflects the non-default value of the corresponding widget option.
The textinput widget wraps input-based widgets in div used for creating the style. textarea elements are not wrapped in such a div.
In the example below, we add the attribute data-corners="false" to the input, because the class ui-corner-all is absent from the wrapper, indicating that the value of the "corners" option should be false.
<label for="pre-rendered-text-field">Pre-rendered input:</label>
<div class="ui-input-text ui-body-inherit ui-shadow-inset">
<input type="text" data-enhanced="true" data-corners="false" name="pre-rendered-text-field" id="pre-rendered-text-field">
</div>
optionName.optionName.This method is provided by the autogrow extension, and it sets the height of the textarea element based on its contents. You should call this method when the textarea element becomes visible to make sure that its initial height matches its contents.
The jQuery Mobile theme provides the CSS framework necessary for providing a consistent and touch-friendly look and feel for your widgets across platforms. It is built around the following essential concepts:
A swatch is one of several colour schemes provided by your theme. We use single-letter designations for swatches. The default jQuery Mobile theme provides two swatches. The "a" swatch is a neutral, gray swatch, and the "b" swatch has a darker color scheme designed to contrast with the "a" swatch. You can use "b" to draw special attention to elements in a user interface styled with "a", and vice versa.
The ThemeRoller allows you to create any number of swatches for a custom theme.
The theme defines an "active" state separately from all the swatches. The intention is to give immediate feedback upon a user action if there should be a brief processing delay. For example, most mobile devices implement a 300ms delay between the time when the user lifts her finger from the touchscreen and the triggering of the "click" event. jQuery Mobile adds the "active" state to a button whenever the device is poised to emit a "click" event so the user receives immediate feedback that the application is committed to processing the "click" in the next 300ms.
You do not need to specify a swatch for every widget you create. Despite this, most widgets have a "theme" option set to null by default so you may override the swatch for an individual widget. The default value of null makes it sufficient to specify a swatch on the outermost container for your user interface. The swatch will then be inherited by all the widgets in the container.
You can override the swatch for portions of a container by specifying a theme swatch for one of its subcontainers.
Note: Because of the nature of CSS, you cannot repeatedly alternate between two swatches.
If you use a widget outside a jQuery Mobile page (or you don't use pages at all) and there is no themed ancestor you have to set the theme option or add the applicable theme class in your markup if you want the widget to be styled. For example, if your panel markup is outside the page and it has a listview inside, you have to set a swatch on the panel for the panel to be styled properly. However, once you set the swatch for the panel, the listview will inherit the swatch from the panel.
The jQuery Mobile throttledresize event is a special event that prevents browsers from running continuous callbacks on resize. throttledresize is used internally for orientationchange in browsers like Internet Explorer. throttledresize ensures that a held event will execute after the timeout so logic that depends on the final conditions after a resize is complete will still execute properly.
The throttledresize event is triggered if orientationchange is not natively supported.
This event triggers when the browser window resizes from:
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .throttledresize() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
var count = 0;
$(function() {
// Bind an event handler to window throttledresize event that, when triggered,
// passes a reference of itself that is accessible by the callback function.
$( window ).on( "throttledresize", throttledresizeHandler );
function throttledresizeHandler( event ) {
$( "#output-text" ).html( "Event Count: " + ++count );
}
// You can also manually force this event to fire.
$( window ).trigger( "throttledresize" );
});
Visit this from your orientation-enabled device to see it in action!
Headers and footers are elements that precede resp. succeed the page content. The toolbar widget allows you to create headers and footers.
The header bar serves as the page title, is usually the first element inside each mobile page, and typically contains a page title and up to two buttons.
The header is a toolbar at the top of the page that usually contains the page title text and optional buttons positioned to the left and/or right of the title for navigation or actions. Headers can optionally be positioned as fixed so they remain at the top of the screen at all times instead of scrolling with the page.
The title text is normally an H1 heading element but it's possible to use any heading level (H1-H6) to allow for semantic flexibility. For example, a page containing multiple mobile "pages" may use a H1 element on the home "page" and a H2 element on the secondary pages. All heading levels are styled identically by default to maintain visual consistency.
<div data-role="header">
<h1> Page Title </h1>
</div>
The toolbar widget uses the jQuery Mobile CSS framework to style its look and feel. If toolbar specific styling is needed, the following CSS class names can be used for overrides or as keys for the classes option:
ui-toolbar-header: The outermost container for toolbar header that provides border.
ui-toolbar-header-button-left: This class can be applied to position buttons to left in toolbar header. You can provide extra classes for left button using classes option and this class as key
ui-toolbar-title: Title element of the toolbar
ui-toolbar-header-button-right: This class can be applied to position buttons to right in toolbar header. You can provide extra classes for right button using classes option and this class as key
ui-toolbar-footer: The outermost container for toolbar header that provides border.
Note: Toolbar footer doesn't provide classes to position button. Refer toolbar demos for more information
ui-toolbar-title: Title element of the toolbar
The header toolbar inherits its theme swatch from the page by default but you can easily set the theme swatch color by adding the data-theme attribute to the header. For example, data-theme="b". When you use external headers you must set a theme, because there is no parent page from which it can inherit a theme.
Note: The behavior whereby anchor elements are automatically enhanced as buttons is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Thereafter you must add button classes if you wish to style them as buttons.
In the standard header configuration, there are slots for buttons on either side of the text heading. Each button is typically an a (anchor) element or a button element that has the attribute data-role="button" set. To save space, buttons in toolbar widgets are set to inline styling so the button is only as wide as the text and icons it contains.
Note: The behavior whereby the first two buttons automatically get the ui-btn-left and ui-btn-right classes is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Thereafter you must add those classes in your markup if you wish to position the buttons left and/or right.
The toolbar plugin looks for immediate children of the header container, and automatically sets the first link in the left button slot and the second link in the right. In this example, the 'Cancel' button will appear in the left slot and 'Save' will appear in the right slot based on their sequence in the source order.
<div data-role="header">
<a href="index.html" data-icon="delete">Cancel</a>
<h1>Edit Contact</h1>
<a href="index.html" data-icon="check">Save</a>
</div>
Buttons automatically adopt the swatch color of the bar they sit in, so a link in a header bar with the "a" color will also be styled as "a" colored buttons. It's simple to make a button visually stand out. Here, we add the data-theme attribute and set the color swatch for the button to "b" to make the "Save" button stand out.
<div data-role="header">
<a href="index.html" data-icon="delete">Cancel</a>
<h1>Edit Contact</h1>
<a href="index.html" data-icon="check" data-theme="b">Save</a>
</div>
The button position can also be controlled by adding classes to the button anchors, rather than relying on source order. This is especially useful if you only want a button in the right slot. To specify the button position, add the class of ui-btn-left or ui-btn-right to the anchor.
<div data-role="header">
<h1>Page Title</h1>
<a href="index.html" data-icon="gear" class="ui-btn-right">Options</a>
</div>
The heading in the header bar has some margin that will give the bar its height. If you choose not to use a heading, you will need to add an element with class="ui-title" so that the bar can get the height and display correctly.
<div data-role="header">
<a href="index.html" data-icon="gear" class="ui-btn-right">Options</a>
<span class="ui-title" />
</div>
Note: The options addBackBtn, backBtnTheme, and backBtnText have moved from the page widget to the toolbar widget as of jQuery Mobile 1.4.0.
jQuery Mobile has a feature to automatically create and append "back" buttons to any header, though it is disabled by default. This is primarily useful in chromeless installed applications, such as those running in a native app webview. The framework automatically generates a "back" button on a header when the toolbar plugin's addBackBtn option is true. This can also be set via markup if the header div has a data-add-back-btn="true" attribute.
If you use the attribute data-rel="back" on an anchor, any clicks on that anchor will mimic the back button, going back one history entry and ignoring the anchor's default href. This is particularly useful when linking back to a named page, such as a link that says "home", or when generating "back" buttons with JavaScript, such as a button to close a dialog. When using this feature in your source markup, be sure to provide a meaningful href that actually points to the URL of the referring page. This will allow the feature to work for users in C-Grade browsers.
If you just want a reverse transition without actually going back in history, you should use the data-direction="reverse" attribute.
If you'd like to configure the back button text, you can either use the data-back-btn-text="previous" attribute on your toolbar element, or set it programmatically via the toolbar plugin's options: $.mobile.toolbar.prototype.options.backBtnText = "previous";
If you'd like to configure the back button role-theme, you can use: $.mobile.toolbar.prototype.options.backBtnTheme = "a";
If you're doing this programmatically, set this option inside the mobileinit event handler.
If you need to create a header that doesn't follow the default configuration, simply wrap your custom styled markup in any container, such as div. The plugin won't apply the automatic button logic to the wrapped content inside the header container so you can write custom styles for laying out the content in your header.
It's also possible to create custom bars without using the header data-role at all. For example, start with any container and add the ui-bar class to apply standard bar padding and add the ui-bar-b class to assign the bar swatch styles from your theme. (The "b" can be any swatch letter.)
<div class="ui-bar ui-bar-b">
<h3>I'm just a div with bar classes and a mini inline <a href="#" data-role="button" data-mini="true">Button</a></h3>
</div>
Note that .ui-bar should not be added to header or footer bars that span the full width of the page, as the additional padding will cause a full-width element to break out of its parent container. To add padding inside of a full-width toolbar, wrap its contents in an element and apply the padding to that element instead.
By writing some simple styles, it's easy to build message bars like this:
The footer bar has the same basic structure as the header except it uses the data-role attribute value of footer.
<div data-role="footer">
<h4>Footer content</h4>
</div>
The footer toolbar inherits its theme swatch from the page by default but you can easily set the theme swatch color by adding the data-theme attribute to the header. For example, data-theme="b". When you use external headers you must set a theme, because there is no parent page from which it can inherit a theme.
The page footer is very similar to the header in terms of options and configuration. The primary difference is that the footer is designed to be less structured than the header to allow more flexibility, so the framework doesn't automatically reserve slots for buttons to the left or right as it does in headers.
Since footers do not have the same prescriptive markup conventions as headers, we recommend using layout grids or writing custom styles to achieve the design you want.
Note: The behavior whereby anchor elements are automatically enhanced as buttons is deprecated as of jQuery Mobile 1.4.0 and will be removed in 1.5.0. Thereafter you must set the attribute data-role="button" on those anchors you wish the framework to enhance as buttons.
Any link or valid button markup with a data-role="button" attribute added to the footer will automatically be turned into a button. To save space, buttons in toolbar widgets are automatically set to inline styling so the button is only as wide as the text and icons it contains.
By default, toolbar widgets don't have any padding to accommodate nav bars and other widgets. To include padding on the bar, add a class="ui-bar" to the footer.
<div data-role="footer" class="ui-bar">
<a href="index.html" class="ui-btn ui-corner-all ui-shadow ui-btn-inline ui-btn-icon-right ui-icon-plus">Add</a>
<a href="index.html" class="ui-btn ui-corner-all ui-shadow ui-btn-inline ui-btn-icon-right ui-icon-arrow-u">Up</a>
<a href="index.html" class="ui-btn ui-corner-all ui-shadow ui-btn-inline ui-btn-icon-right ui-icon-arrow-d">Down</a>
</div>
This creates this toolbar with buttons sitting in a row
Note that .ui-bar should not be added to header or footer bars that span the full width of the page, as the additional padding will cause a full-width element to break out of its parent container. To add padding inside of a full-width toolbar, wrap the contents of the toolbar widget in an element and apply the padding to that element.
To group buttons together into a button set, wrap the links in a wrapper with data-role="controlgroup" and data-type="horizontal" attributes.
<div data-role="controlgroup" data-type="horizontal">
This creates a grouped set of buttons:
Form elements and other content can also be added to toolbars. Here is an example of a select menu inside a footer bar. We recommend using mini-sized form elements in toolbars by adding the data-mini="true" attribute:
In situations where the footer is a global navigation element, you may want it to appear fixed so it doesn't scroll out of view. It's also possible to make a fixed toolbar persistent so it appears to not move between page transitions. This can be accomplished by using the persistent footer feature included in jQuery Mobile.
To make a footer persistent between transitions, add the data-id attribute to the footer of all relevant pages and use the same id value for each. For example, by adding data-id="myfooter" to the current page and the target page, the framework will keep the footer anchors in the same spot during the page animation. This effect will only work correctly if the header and footer toolbars are set to data-position="fixed" so they are in view during the transition.
In browsers that support CSS position: fixed (most desktop browsers, iOS5+, Android 2.2+, BlackBerry 6, and others), toolbar widgets that use the "fixedtoolbar" plugin will be fixed to the top or bottom of the viewport, while the page content scrolls freely in between. In browsers that don't support fixed positioning, the toolbars will remain positioned in flow, at the top or bottom of the page.
To enable this behavior on a header or footer, add the data-position="fixed" attribute to a jQuery Mobile toolbar element.
Fixed header markup example:
<div data-role="header" data-position="fixed">
<h1>Fixed Header</h1>
</div>
Fixed footer markup example:
<div data-role="footer" data-position="fixed">
<h1>Fixed Footer</h1>
</div>
Note: When you dynamically inject a fixed toolbar into the active page, you must afterwards call $.mobile.resetActivePageHeight(); to ensure that the page height remains correct. An example illustrates this.
Fullscreen fixed toolbars sit on top of the content at all times when they are visible, and unlike regular fixed toolbars, fullscreen toolbars do not fall back to static positioning when toggled. Instead they disappear from the screen entirely. Fullscreen toolbars are ideal for more immersive interfaces, like a photo viewer that is meant to fill the entire screen with the photo itself and no distractions.
To enable this option on a fixed header or footer, add the data-fullscreen attribute to the element.
<div data-role="header" data-position="fixed" data-fullscreen="true">
<h1>Fullscreen fixed header</h1>
</div>
While all form elements are now tested to work correctly within static toolbars as of jQuery Mobile 1.1, we recommend extensive testing when using form elements within fixed toolbars or within any position: fixed elements. This can potentially trigger a number of unpredictable issues in various mobile browsers, Android 2.2/2.3 in particular (detailed in Known issues in Android 2.2/2.3, below).
Prior to version 1.1, jQuery Mobile used dynamically re-positioned toolbars for the fixed header effect because very few mobile browsers supported the position:fixed CSS property, and simulating fixed support through the use of "fake" JavaScript overflow-scrolling behavior would have reduced our browser support reach, in addition to feeling unnatural on certain platforms. This behavior was not ideal, and jQuery Mobile 1.1 took a new approach to fixed toolbars that allows much broader support. The framework now offers true fixed toolbars on many popular platforms, while gracefully degrading non-supporting platforms to static positioning.
The fixed toolbar plugin degrades gracefully on platforms that do not support CSS position:fixed properly, such as iOS4.3. If you still need to support fixed toolbars on that platform (with the show/hide behavior) included in previous releases, Filament Group has developed a polyfill that you can use.
Just include the CSS and JS files after your references to jQuery Mobile and Fixed toolbars will work similarly to jQuery Mobile 1.0 on iOS4.3, with the inclusion of the new API for the 1.1 fixedtoolbar plugin.
If you have any improvements to suggest, fork the gist on github and let us know!
An obscure issue exists in iOS5 and some Android platforms where form controls placed inside fixed-positioned containers can lose their hit area when the window is programatically scrolled (using window.scrollTo for example). This is not an issue specific to jQuery Mobile, but because of it, we recommend not programatically scrolling a document when using form controls inside jQuery Mobile fixed toolbars. This ticket from the Device Bugs project tracker explains this problem in more detail.
Android 2.2/2.3's implementation of position: fixed; can, in conjunction with seemingly unrelated styles and markup patterns, cause a number of strange issues, particularly in the case of position: absolute elements inside of position: fixed elements. While we've done our best to work around a number of these unique bugs within the scope of the library, custom styles may cause a number of issues.
position: fixed element appears anywhere on a page, most 2D CSS transforms will fail. Oddly, only translate transforms seem unaffected by this. Even more oddly, this issue is solved by setting a CSS opacity of .9 or below on the parent of the fixed element.position: fixed and overflow properties are best avoided, as both have been known to cause unpredictable issues in older versions of Android OS.position: fixed element, will fail to respond to user input when using anything other than the default keyboard. This includes Swype, XT9 or, it seems, any input method apart from the standard non-predictive keyboard.While we will continue to try to find ways to mitigate these bugs as best we can, we currently advise against implementing fixed toolbars containing complicated user styles and form elements without extensive testing in all versions of Android's native browser.
Prior to jQuery Mobile 1.1, true fixed toolbar support was contingent on native browser support for the CSS property overflow-scrolling: touch, which is currently only supported in iOS5. As of version 1.1, jQuery Mobile no longer uses this CSS property at all. We've removed all internal usage of this property in the framework, but we've left it defined globally on the $.mobile object to reduce the risk that its removal will cause trouble with existing applications. This property is flagged for removal, so please update your code to no longer use it. The support test for this property, however, remains defined under $.support and we have no plans to remove that test at this time.
fixedToolbar extension.
Hides the toolbar.
optionName.optionName.If you manipulate a toolbar via JavaScript, you must call the refresh method on it to update the visual styling.
fixedToolbar extension.
Shows the toolbar.
fixedToolbar extension.
Calls either the show or the hide method, depending on whether the toolbar is visible.
$.mobile.document.on( "click", "#inject-toolbar", function() {
$( "<div data-role='header'><h1>Dynamic Fixed Toolbar Header</h1></div>")
.appendTo( $( "#inject-toolbar" ).closest( ".ui-page" ) )
.toolbar({ position: "fixed" });
// This second step ensures that the insertion of the new toolbar does not
// affect page height
$.mobile.resetActivePageHeight();
});
Some components within the framework, such as collapsible and listview search, dynamically hide and show content based on user events. This hiding/showing of content affects the size of the page and may result in the browser adjusting/scrolling the viewport to accommodate the new page size. Since this has the potential to affect other components such as fixed headers and footers, components like collapsible and listview trigger a custom updatelayout event to notify other components that they may need to adjust their layouts in response to their content changes. Developers who are building dynamic applications that inject, hide, or remove content from the page, or manipulate it in any way that affects the dimensions of the page, can also manually trigger this updatelayout event to ensure components on the page update in response to the changes.
This event is triggered by components within the framework that dynamically show/hide content, and is meant as a generic mechanism to notify other components that they may need to update their size or position. Within the framework, this event is fired on the component element whose content was shown/hidden, and bubbles all the way up to the document element.
$( "#foo" ).hide().trigger( "updatelayout" );
We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmouseup is always dispatched before vmousedown, and vmousedown before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
The jQuery Mobile "vclick" event handler simulates the "onclick" event handler on mobile devices.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vclick() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
$( document ).on( "vclick", "p", function() {
$( this ).append( "<span style='color:#108040;'> vclick fired... </span>" );
});
Use vclick with caution on touch devices. Webkit based browsers synthesize mousedown, mouseup, and click events roughly 300ms after the touchend event is dispatched. The target of the synthesized mouse events are calculated at the time they are dispatched and are based on the location of the touch events and, in some cases, the implementation specific heuristics which leads to different target calculations on different devices and even different OS versions for the same device. This means the target element within the original touch events could be different from the target element within the synthesized mouse events.
We recommend using click instead of vclick anytime the action being triggered has the possibility of changing the content underneath the point that was touched on screen. This includes page transitions and other behaviors such as collapse/expand that could result in the screen shifting or content being completely replaced.
Applications can call preventDefault() on a vclick event to cancel an element's default click behavior. On mouse based devices, calling preventDefault() on a vclick event equates to calling preventDefault() on the real click event during the bubble event phase. On touch based devices, it's a bit more complicated since the actual click event is dispatched about 300ms after the vclick event is dispatched. For touch devices, calling preventDefault() on a vclick event triggers some code in the vmouse plugin that attempts to catch the next click event that gets dispatched by the browser, during the capture event phase, and calls preventDefault() and stopPropagation() on it. As mentioned in the warning above, it is sometimes difficult to match up a touch event with its corresponding mouse event because the targets can differ. For this reason, the vmouse plugin also falls back to attempting to identify a corresponding click event by coordinates. There are still cases where both target and coordinate identification fail, which results in the click event being dispatched and either triggering the default action of the element, or in the case where content has been shifted or replaced, triggering a click on a different element. If this happens on a regular basis for a given element/control, we suggest you use click for triggering your action.
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold (default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold (default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration (default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmouseup is always dispatched before vmousedown, and vmousedown before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
The jQuery Mobile vmousecancel event handler is called whenever the system cancels a virtualized mouse event. This event occurs when a scroll is triggered. jQuery Mobile will fire a "vmousecancel" event in this instance.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vmousecancel() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold (default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold (default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration (default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmousedown is always dispatched before vmouseup, and vmouseup before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
The jQuery Mobile vmousedown event handler simulates the "onmousedown" event handler on mobile devices.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vmousedown() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
$( function () {
$( document ).on( "vmousedown", "p", function() {
$( this ).append( "<span style='color:#108040;'> vmousedown fired...</span>" );
});
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold (default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold (default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration (default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmouseup is always dispatched before vmousedown, and vmousedown before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
The jQuery Mobile vmousemove event handler simulates the "onmousemove" event handler on mobile devices.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vmousemove() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
$( function () {
$( document ).on ( "vmousemove", "#target", function(event) {
var msg = "Handler for .vmousemove() called at ";
msg += event.pageX + ", " + event.pageY;
$( "#log" ).append( " <div>" + msg + "</div>" );
});
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold (default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold (default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration (default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmouseup is always dispatched before vmousedown, and vmousedown before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
The jQuery Mobile vmouseout event handler simulates the "onmouseout" event handler on mobile devices.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vmouseout() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
$( document ).on( "vmouseout", "p", function() {
$( this ).append ( "<span style='color:#108040;'> vmouseout fired...</span>" );
});
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold (default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold (default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration (default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmouseup is always dispatched before vmousedown, and vmousedown before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
The jQuery Mobile "vmouseover" event handler simulates the "onmouseover" event handler on mobile devices.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vmouseover() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
$( document ).on( "vmouseover", "p", function() {
$( this ).append( "<span style='color:#108040;'> vmouseover fired...</span>" );
});
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold (default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold (default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration (default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.We provide a set of "virtual" mouse events that attempt to abstract away mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. In touch environments, the plugin retains the order of event firing that is seen in traditional mouse environments, so for example, vmouseup is always dispatched before vmousedown, and vmousedown before vclick, etc. The virtual mouse events also normalize how coordinate information is extracted from the event, so in touch based environments, coordinates are available from the pageX, pageY, screenX, screenY, clientX, and clientY properties, directly on the event object.
The jQuery Mobile "vmouseup" event handler simulates the "onmouseup" event handler on mobile devices.
This plugin extends jQuery's built-in method. If jQuery Mobile is not loaded, calling the .vmouseup() method may not fail directly, as the method still exists. However, the expected behavior will not occur.
$( document ).on( "vmouseup", "p", function() {
$( this ).append( "<span style='color:#108040;'> vmouseup fired...</span>" );
});
The virtual mouse events can also be configured:
$.vmouse.moveDistanceThreshold (default: 10px) – More than this, then it is a scroll event. The vmousecancel event is called and the TouchMove event is cancelled.$.vmouse.clickDistanceThreshold (default: 10px) – If a vclick event was already captured and is in the block list, then vclicks less than this distance are ignored.$.vmouse.resetTimerDuration (default: 1500ms) – More time than this, then it is not a touch event. Scroll, TouchMove and TouchEnd events use this. The block list is cleared.