jQuery Mobile Components
Hello. This is the second in a short run of articles aimed at explaining the basics of jQuery Mobile. In the introductory article Hello jQuery Mobile we covered getting set up, page structures, navigation, transitions and basic list views.
In so doing, we built out a reference site, which demonstrates the use of CSS to create shapes without images. This article continues development of that CSS3 Shapes reference site, and continues to refer to our new best friend as jQM, but this time around we’ll take a whistle stop tour of Components.
On the Cutting Edge
When we introduced you to jQM it was noted the code was in an Alpha state. Since then the first jQM Beta hit the streets. There are many ways to keep abreast of such developments, which we’ll come back to in a moment. For the hardcore there is, of course, the jQuery Mobile GitHub repository.
I am attracted to the GitHub repo because, as noted in the
README.md, you can have the docs & demos running locally, with the double benefit of an up-to-the-minute jQM build. We are going to clone a copy of the repository. If you’re not on the Git bandwagon by now, shame on you. It’s not too late.
You need a local web server. I am using MAMP configured to run in the “Sites” folder on Mac OS X, so I’ll create a new ‘jQueryMobile’ folder in ‘Sites’. Then enter the following commands in Terminal, one at a time. Admittedly, this is particular to my environment, so you may need to make minor tweaks.
Clone the jQM Repo
cd ~/sites/jquerymobile git clone git://github.com/jquery/jquery-mobile.git cd jquery-mobile make
That is all. Point your browser to our new
jquerymobile/jquery-mobile/ folder, behold the local docs and demos! The project is inside the
jquery-mobile folder, which gets created during the clone. This is awesome for doing some development at the park or cafe, and its quicker to browse.
As a result of the
make command you will have a folder called
compiled, which contains fresh as a daisy copies of the
*.css files. Copy the new files into the
jqm folder of our reference project, update the links in the
<head> and we are right on the cutting edge.
Note, the images in the first Beta are the same as the Alpha but if they did change, or you are doing this for the first time, add or update
/images/ with those from
/themes/default/images/. Finally, note that jQuery is up to 1.6.1 and the jQM project uses it, so update that file as well.
Keeping Abreast of Developments
It’s important to keep abreast of developments. Besides GitHub, read the jQuery Mobile Blog, and follow the developers on Twitter, wherein folks like @scottjehl announce updates and suggest required reading. This is especially important because jQM is developing quite rapidly right now.
For example, pinch-to-zoom was disabled up to Alpha and has been restored in the Beta, for various reasons as explained in the Beta 1 Release Post. From now on, developers must add the
meta viewport tag to the markup, where before it was inserted dynamically.
All In The Head
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>CSS3 Shapes</title> <link rel="stylesheet" href="jqm/jquery.mobile-1.0b2pre.min.css" /> <script src="jqm/jquery-1.6.1.min.js"></script> <script src="jqm/jquery.mobile-1.0b2pre.min.js"></script> </head>
With these additions to the
<head>, our reference site will now scale properly, wherein the column width is narrow but the text and icons remain full size. The friendly developers help where they can, but make sure you stay up to date where you can, especially whilst the jQM project incubates.
No Going Back
At this stage we have the original reference project, with updated jQM code files in the
/jqm/ folder and an updated
meta viewport tag. Fire up your reference site, and note the lack of ‘Back’ button on pages beyond the home page or
index.html. The “Back” button is now off by default, as predicted.
A simple fix is to add
data-add-back-btn="true" to each
data-role="page" element, which restores the ‘Back’ button. This button ignores the
href and goes back one history entry. The equivalent manual code would be
<a href="index.html" data-icon="arrow-l" data-rel="back">Back</a>
But let’s think about this manual code, because it presents some complexity when you are coding links all over your site. The docs say you should provide a meaningful
href for C grade browsers that actually points back to the referring page. This means you need to write code to dynamically populate the
href to point back to the previous page.
When the buttons are added programatically using the
data-add-back-btn="true" attribute, jQM adds a simple
Header Toolbar & Buttons
There is a slot for buttons either side of the the text in a
data-role="header" element, so that’s two in a standard configuration. The jQM header plugin looks for immediate children of the
data-role="header", the first link it finds goes to the left, and the second goes to the right.
Once we have left the home page, let’s add a “Home” button to the header, by adding
<a href="#shapes" data-icon="home">Home</a> inside the
data-role="header" element. With that, and that alone, you’ll wonder where our “Back” button has gone. Take control of position by adding
class="ui-btn-right", and the “Back” button returns to view because the “Home” button is out of its way to the right.
If we add the
data-rel="back" to the “Home” button link, jQM will remove one item from the history stack and reverse the transition, when it is touched or clicked. Adding
data-iconpos="notext" removes the text from the button, but we can leave the text in the markup regardless.
<header data-role="header"> <h1>Shape</h1> <a href="#shapes" class="ui-btn-right" data-rel="back">Home</a> </header>
This is fine when we’re one step away from the ‘Home’ page, but when we’re two steps away on a ‘CSS’ page the markup will have to change, because
data-rel="back" will go back to a ‘Shape’ page instead of ‘Home’. So we’ll use a meaningful
data-direction="reverse", which means we get the left-to-right slide, and the mental model remains intact.
Note, there is a bug where
Footer Toolbar & Fixed Positioning
Essentially the same rules that apply to
data-role="header" apply to
data-role="footer". The primary difference is that there is less structure, such that buttons are not placed left and right, instead they are all inline.
A cool feature is to keep
data-role="footer" firmly in place between transitions, by using a common
data-id="". Note, this requires that the
data-role="footer" use fixed positioning.
To take advantage of native scrolling and have the toolbars re-appear after a scroll, use
data-position="fixed". Add this snippet to all of the
data-role="footer" elements in the code.
Now we can add a persistent footer, by adding a common
data-id="footer" to every
data-role="footer" element. Note, the
data-position="fixed" set on all
data-role="footer" elements means it is global element. Now we have a fixed position
footer that remains static during page transitions. Cool.
<footer data-role="footer" data-position="fixed" data-id="footer"> ... </footer>
Dialogs & Data Icons
data-role="footer" is a global element, we’ll put something global in there like a page about the web app. We’ll make our page about the app present itself as a dialog, to demonstrate the code and talk about the implications. First thing to note, dialogs are not included in the hash state history tracking.
Create a new
data-role="page" element at the bottom of the source, to maintain sensible source order. This page has a slightly different structure, a simple
data-role="header" including our ‘Home’ button. There is no
data-position="fixed" applied to the
data-role="header" because that would destroy the modal dialog. There is no
data-role="footer" at all because that, too, would destroy the modal dialog.
Next, in the
data-role="footer" element of all standard
data-role="page" elements, add a link to the new dialog. Add
data-rel="dialog" to the link to ensure the linked page will present as a dialog. We’ll choose a
data-icon="" for the button image, we are using
The default transition for a modal dialog is a
data-transition="pop" otherwise it is recommended to use
flip to make it feel more dialog-like. Padding is off by default, so we need to add it back in for buttons, navbars and other widgets. Add
class="ui-bar" to all
data-role="footer" elements, when using them this way.
<footer data-role="footer" data-position="fixed" data-id="footer" class="ui-bar"> <a href="#about" data-rel="dialog" data-icon="gear" data-transition="pop">About</a> </footer>
We can style any anchor link as a button by adding
data-role="button". By default the buttons fill the available screen width. Make buttons compact, and only as wide as the text and icons they contain by using the
data-inline="true" attribute. Set buttons side by side by wrapping them in a containing element with the
data-inline="true" attribute applied.
Group buttons in a block by wrapping them in a container with the
data-role="controlgroup" attribute applied. Stacked vertically by default, change to a horizontal group by adding
data-type="horizontal" to the
Adding icons to buttons is achieved with the
data-icon="" attribute. jQM ships with a couple of sprites that include a selection of icons most often needed for mobile apps, simply specify your icon choice in the attribute. Position is left of the text by default, but the position of the button icon can be controlled using the
For our reference app, we’ll stick to a simple
controlgroup with two
data-role="button" elements, one for the ‘Shape’ and one for the ‘CSS’. We’ll apply this pattern to each of the ‘Shape’ and ‘CSS’ pages, therein providing a quick toggle between the shape and the code used to produce each.
<nav data-role="controlgroup"> <a data-role="button">Shape</a> <a href="#shape_css" data-role="button" data-transition="pop">CSS</a> </nav>
<nav data-role="controlgroup"> <a href="#shape" data-role="button" data-rel="back">Shape</a> <a data-role="button">CSS</a> </nav>
Our good friend jQM includes a wide range of list types and formatting options to cover most common design patterns, all of which are simple to use by adding
data items to the markup. We covered a fair amount of the options in the first article Hello jQuery Mobile. But one more quick example.
We’ll add an index for all ‘Shapes’ and all ‘CSS’ pages to our About dialog. Add an
<h4> to act as a header to each list, then the plain old semantic HTML elements of
<li> sequences for the items. Two additional
data items are all we need to add, and they are
<ul data-role="listview" data-inset="true">. This results in two inset lists in the About page.
<h4>Shapes</h4> <ul data-role="listview" data-inset="true"> <li><a href="#circle">Circle</a></li> ... </ul>
jQM takes a gentle approach to content styling, allowing the browser’s native rendering to take precedence, adding just a little bit of padding for comfortable reading. You can use the theming system to take control of typeface and colour. And we’ll save the Theme Framework for a later fireside chat.
Back to layout. jQM provides a simple way to achieve CSS based columns through a convention called
ui-grid. Although multiple column layouts are tough in the mobile environment, layout grids can be achieved in a few preset configurations.
For a two column grid, simply add a
class="ui-grid-a" to a containing element, and inside that add elements with
class="ui-block-b". A three column grid uses a container with
class="ui-grid-b" applied, and expects
class="ui-block-c" inside it.
Finally, note that multiple row grids can be achieved by adding, say, four child blocks to a two column grid, six or nine blocks to a three column grid. Cycle through
class="ui-block-b" and so on as applicable to your desired layout
Multiple Row Grid
<div class="ui-grid-b"> <div class="ui-block-a">Row 1 Cell 1</div> <div class="ui-block-b">Row 1 Cell 2</div> <div class="ui-block-c">Row 1 Cell 3</div> <div class="ui-block-a">Row 2 Cell 1</div> <div class="ui-block-b">Row 2 Cell 2</div> <div class="ui-block-c">Row 2 Cell 3</div> </div>
And the content formatting fun just keeps coming, with collapsible blocks. Collapsible content blocks are created by adding a
data-role="collapsible" attribute to a container, wherein jQM will add a “+/–” icon to a
heading element placed immediately inside the container.
heading element of
<h1> through an
<h6>, which remains visible with the expansion icon, then markup the remainder of the content inside the
data-role="collapsible" container, whose visibility can then be toggled on and off with the
<div data-role="collapsible"> <h3>Header & Icon</h3> <p>Collapsible Content</p> </div>
As we head for the finish line, a quick note that the content area of a page should take the majority of its styles from the
data-theme="x" attribute applied to the
data-role="page" element. There is a comprehensive object oriented CSS framework within jQM that you can take and make in your own image.
Thus far, we have covered the basics of getting up and running with jQM followed by a whistlestop tour of the components you can use simply by adding to your markup. Everything we have done has been achieved with markup alone.
There is great depth to be discovered, and we have barely scratched the surface. If you are lucky enough to start courting jQM you might discover her rich APIs, which relate to events, methods and utilities, the responsive layout and the theme framework.
Check out the complete reference site at 3Easy. Please leave your thoughts and questions in the comments, and be so bold as to request where you might like to go next. Thanks for stopping by, for now I bid you farewell. I got a date with jQM.