A Deeper Dive into jQuery Mobile

Wallace B. McClure | January 9, 2013

Download the Code Sample

There’s no doubt that mobile Web applications are here to stay. As I said at the start of the previous article in this series, talk to any C-level executive at a major company or any technology startup, and they’ll tell you about mobile apps.

jQuery Mobile (jQM) provides a JavaScript framework that allows developers to easily add a mobile look and feel to their Web applications. In this article I’ll dig into some advanced features of jQuery Mobile that—with some programming—a developer can use to provide an application that looks and feels very similar to a native app running on a device. Here’s what I’ll cover:

  • $.mobile. You’ll learn what the $.mobile object is, how to use it and how to set values globally in an application.
  • ListView.  We previously looked at the ListView at a high level. In this article I’ll describe more advanced features of the ListView that developers can use to provide the mobile equivalent of the iOS UITableView and the Android Listview.
  • Navbar.  Native applications typically have a navbar that provides navigation for an application.  I’ll go into the more advanced concepts of the navbar, which let you provide users with a consistent navigation experience across an application.

Configuration of jQuery Mobile

jQM comes with a new object—the mobile object—which is available off the main jQuery object, $. The $.mobile object contains a set of attributes and methods that developers can use in a jQM application to improve the default experience. 

Note: The $.mobile object is not available until after the mobileinit event is fired.

In the previous article, I described examples of using a “data-”attribute on elements. Typically, these attributes are applied to every element. Sometimes, you need to apply these attributes at a global level. This can be done in the mobileinit event using the $.mobile object. 

For example, the $.mobile object can be extended as follows:

$(document).bind("mobileinit", function(){
  $.mobile.blah = val;
});
Or by doing this:
$(document).bind("mobileinit", function(){
  $.extend(  $.mobile , {
    blah: val
  });
});

In these simple samples, the $.mobile object has a new property named “blah” added to it.  (I so hate using “foo” and “bar”.)

In the next example, when the mobileinit event fires, two settings are configured.  In this specific example:

  • The property addBackBtn is set to true.  This sets subsequent pages to display the Back button at the top left of the display.
  • The property backBtnText is set to “back”.  This sets the text on the Back button.
@{
  Page.Title = "$.mobile configuration";
  Layout = "~/_SiteLayout.cshtml";
}
@section Head{
<script>
  $(document).bind('mobileinit', function () {
    $.mobile.page.prototype.options.addBackBtn = true;
    $.mobile.page.prototype.options.backBtnText = "back";
  });
</script>
}
<div>
  <a href="About">About app</a>
</div>

This code results in the display shown in Figure 1 when the “About app” link is selected by the user.

The Back Button with Text
Figure 1. The Back Button with Text

This example shows only two of the properties that can be set. There are many more, including:

  • activeBtnClass. A string representing the CSS class used for the “active” button state. The default value for this property is “ui-btn-active”.
  • activePageClass.  A string representing the CSS class used for the page currently in view or in transition. The default value for this property is “ui-page-active”.
  • ajaxEnabled.  A Boolean that controls how jQM handles the AJAX loading of pages when users click links and submit forms. The default for this property is true. If the property is set to false, clicking on links and submitting forms are handled as regular HTTP requests, and none of the sexy AJAX loading is used.
  • allowCrossDomainPages. A Boolean that controls how cross-domain page loads are handled when the $.mobile.loadPage method is called. The default value for this property is false.  Setting the value to true opens up the application to a cross-site scripting attack (XSS). The possibility is somewhat limited, but an attack can occur.
  • defaultDialogTransition. The default transition for dialog changes that use AJAX. The default value for this property is “pop”.  Setting this value to “none” results in no transitions.
  • defaultPageTransition. The default transition for page changes that are performed via AJAX.  The default value is “fade”.  This is a change from jQM 1.0, where the default value is “slide”.  Setting this value to “none” results in no transitions between pages.
  • loadingMessage. Sets the text that appears when a page is in the process of being loaded.  The default value is “loading”.  With jQM 1.2, this property has been deprecated. The property to be used going forward is $.mobile.loader.prototype.options.text.

In addition to the properties listed, numerous other properties can be used. Check the resources list at the end of this article for a link to the full list.

The Page Loading Widget

Control over the configuration of page loading was previously accomplished by several properties of the $.mobile object. These properties have been pulled out of jQM and are now part of the $.mobile.loader.prototype.options object.  The properties of interest are:

  • text. A string that sets the text that’s displayed when a page is loaded via AJAX.
  • textVisible. A Boolean that determines whether or not the text is displayed when a page is loaded.
  • theme. Sets the theme of the pages.

Events

In the previous article, I mentioned several events that are available within jQM. Instead of going into a long-winded discussion of each of these events, let me point out two things I’ve found helpful:

  • Expect changes. I’ve found subtle changes between jQM 1.0, 1.1, and 1.2 regarding how events work (or at least my understanding of them). I expect additional changes going forward—it’s definitely the nature of the mobile environment at this point in time. Be flexible and understand that there may be changes to code as jQM matures.
  • From personal experience, the mobileinit method is very useful for making the necessary changes to the configuration of $.mobile. It is not as helpful for accessing DOM objects. As a result, developers should look at using pageinit when attempting to access objects in the DOM.

Methods and Utilities

A number of methods and utilities are available via the $.mobile object. The methods involved with changing pages or URLs seem to be used the most. These methods are:

  • $.mobile.changePage(url, options). The URL is the page to be loaded. The URL can be relative or absolute. The options object is a JSON object that will change the default behavior of the page being loaded.
  • $.mobile.loadPage(url, options). This is the URL of the page to be loaded. The URL can be relative or absolute. The options object is a JSON object that will change the default behavior of the page being loaded. The difference between changePage and loadPage is that loadPage does not change the currently active page.

For a complete list of methods and utilities, see the list here (also included in this article’s references).

ListView

In the previous article, I introduced the ListView. The ListView widget is a grid that holds data, can be populated and is optimized for the display of content on a mobile device. Here, we’ll take a deeper look at working with the ListView, specifically how you can fill the ListView with content via AJAX data.

AJAX has been a boon for Web applications since developers started using it back in 2005. For desktop Web applications, AJAX has provided a quicker response because the browser does not have to go back to the server for a result. This means less data transferred between the browser and the server, and less data means a quicker response. 

In the mobile world, AJAX has additional benefits. Networks in the mobile world are not very dependable. A phone can have full high-speed connectivity at one moment and then have little if any connectivity at another. This can happen when a phone’s user enters a building, a user walks around one side of a building to another, the train a user is on goes through a tunnel or any number of other things. Interruptions like these can happen during the course of running an application. By transferring less data, AJAX places less of a load on the network, less data is sent to the server, less processing occurs on the server and less data is sent to the mobile device. The result is a better user experience, and in the mobile world, the user’s experience is more important than in the desktop Web world.

An additional advantage of AJAX is that the operation is asynchronous. In the mobile world, applications that lock the UI thread are typically killed by the operating system. If an AJAX operation was synchronous, it would typically lock the UI thread being used by the browser. Because AJAX is asynchronous, the browser won’t lock the UI thread, and the browser won’t be killed by the operating system.

The following example looks at binding some data to a ListView. This code starts with the data already on the client, though having it in a JSON format shows that the ListView can be manipulated in a dynamic way. In this situation, the data shows the BCS college football rankings going into the final weekend of the season. When the page loads, the pageinit event is processed. The pageinit event is fired once the DOM is loaded. In the pageinit event, the code iterates through the array of JSON objects, and once the content is created in the form of a loop, a reference to the div with the ID of BookContainer is created. The content is added to the div via the jQuery .append method. (Other options are available, such as .empty.) The final operation performed is the refresh method on the ListView. Figure 2 shows the output of the code.

Note:  The .refresh method affects only new nodes that have been appended to a ListView. If a program needs to update a list item, the program must replace the list items with fresh markup.

<ul id="BookContainer"data-role="listview" data-theme="b"></ul>
@section head{
<script>
  var schoolInfo = [
    { Ranking: "1", School: "Notre Dame"},
    { Ranking: "2", School: "Alabama" },
    { Ranking: "3", School: "Georgia" },
    { Ranking: "4", School: "Oregon" },
    { Ranking: "5", School: "Kansas State"}];
  function SetupListView(){
    var content = "";
    for (i = 0; i < schoolInfo.length; i++) {
      content += "<li class='ul-li-icon'><a href='#'>" + 
        schoolInfo[i].School + " Ranking: " +
        schoolInfo[i].Ranking + "</a></li>";
    }
    $("#BookContainer").append(content);
    $("#BookContainer").listview("refresh");
  }
  $(document).bind('pageinit', function() {
    SetupListView();
  });
</script>
}

A Dynamically Filled ListView
Figure 2. A Dynamically Filled ListView

Headers, Footers, and Navigation Bars

Mobile applications tend to have various areas of the screen that are used for standard toolbars. These toolbars include the header, the footer, and the tab/navigation bar. jQM supports all three types of standard toolbars.

Header. A header toolbar is displayed at the top of a page. It consists of a page title and optional buttons that can be configured on the right and left of the title. By default, the header toolbar is themed with the “a” swatch. Buttons can be added with the <a> tag. The text within the header is typically displayed with the <h1> tag.

Footer. The footer toolbar is similar in concept to the header, the biggest difference being that the footer can contain more buttons. At the same time, developers need to remember that too many buttons can create problems. (Please be mindful of users when developing an application.)

Navbar. The jQM navbar is a widget that can display up to five buttons in a bar. The widget is typically used within the header or footer.

Toolbar Positioning

By default, the header and footer can be placed on a page in several different ways:

  • The default inline-positioning mode. In this mode, the header and footer sit in the natural document flow of the page. The header and footer scroll with the page and are visible on all devices.
  • The fixed-positioning mode. In this mode, the toolbars are fixed to the top and bottom of the viewing area of the browser. This mode is supported on iOS5 and later, Android 2.2 and later, Blackberry 6 and later, most desktop browsers and browsers that support the CSS position: fixed property. In these browsers, the toolbars will be fixed to the top and bottom of the viewing area, and the content will scroll between the headers and footers. When the browser does not support fixed positioning, the header and footer will scroll within the content.
  • The full-screen position mode works similarly to the fixed-position mode. The difference is that the toolbars will overlay the page content instead of reserving a place within the document.

Now that you know the numerous options, let’s look at a code sample, which results in the output shown in Figure 3. This sample contains:

  • A header with the data-position attribute set to fixed.
  • A button to perform the save function, which is displayed within the header. The button has a check mark icon associated with it and is aligned to the right. The first button added is typically set to the left side of the header, but adding the jQM class ui-btn-right causes the button to be aligned on the right of the header by default.  Finally, a different data-theme attribute value is used.  This causes the button to stand out visually.
  • A navbar within the header.  The contacts button is the default button. This is set via the class ui-btn-active.
  • A  footer in the fixed position. 
  • A navbar displayed within the footer.
<div data-role="page" data-theme="c">
  <div data-role="header" data-position="fixed">
  <h1>Customers</h1>
  <a href="#" data-icon="check" data-theme="b" class="ui-btn-right">Save</a>
    <div data-role="navbar">
      <ul>
        <li><a href="contacts.cshtml" class="ui-btn-active">Contacts</a></li>
        <li><a href="orders.cshtml">Order</a></li>
      </ul>
    </div>
  </div>
  <div data-role="content">
    <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<!--Put content here-->    
  </div>
  <div data-role="footer" data-position="fixed">
    <h4>More info</h4>
    <div data-role="navbar">
      <ul>
        <li><a href="contacts.cshtml" class="ui-btn-active">Contacts</a></li>
        <li><a href="orders.cshtml">Order</a></li>
      </ul>
    </div>
    <h4>Tuesday, December 04, 2012 - Copyright SDI</h4>
  </div>
</div>

Header and footer fixed along with navbars
Figure 3. Header and footer fixed along with navbars (left: Internet Explorer 9; right: Android 4 Ice Cream Sandwich)

Wrapping Up

In this look at some of the more advanced features of jQM, I’ve explored configuring jQM with the $.mobile object. Configuring settings for jQM globally means the settings won’t have to be configured on each page of the application. This saves time in the development process if a change must be made globally.

This piece also looked at dynamically using the ListView to display data in an optimal way. By loading data via AJAX calls and then displaying the data in the ListView, the amount of data sent across the connection is minimized, resulting in a better experience for the users. When users are happy, developers are happy.

In the next installment of this series, I dive deeper into using and creating custom themes that give your apps a specific look.

References

About the Author

Wallace McClure is a redneck from Tennessee who somehow found his way to Atlanta and Georgia Tech. He was lucky enough to graduate from there twice, with a BS and MS in electrical engineering. He’s always loved things that were new and different, which led to his love of writing software (starting in COBOL and x86 asm), digging into Microsoft's Web technologies, jumping whole-hog into the .NET Framework 1.0 beta, following in love with mobile way back in 1999, and a whole host of things he probably shouldn't have done but did anyway. Somewhere along the way, he was contacted by someone representing a publisher that would eventually get purchased by John Wiley and Sons and folded into their Wrox division. Several books later, he’s run the gamut from software architecture, to scaling applications, ADO.NET, SQL Server, Oracle, Web, AJAX and mobile technologies. He’s worked for startup companies and many different organizations, all the way up through U.S. federal government agencies.

When not writing software, writing about software, talking about software or thinking he is a comedian, Wally can be found playing golf, in the gym or coaching basketball.

Find Wally on: