Data-driven interactive applications with HTML5 and Ajax

Cross-platform Web apps for online or offline use

As the number of mobile platforms increases, developing cross-platform standards-based applications becomes increasingly attractive. HTML5 offers the ability to write complete mobile-friendly applications that include offline use, just like their native-application counterparts. Discover how to create offline-capable web applications using only open source tools and techniques familiar to web developers.

Share:

Liza Daly, Software Engineer and Owner, Threepress Consulting Inc.

Photo of Liza DalyLiza Daly is the president of Threepress Consulting Inc. and an experienced software engineer in Web applications and digital publishing. In 2010, she released Ibis Reader, the first HTML5 mobile e-reader. You can reach Liza at liza@threepress.org.



05 October 2010

Also available in Russian Japanese Portuguese

HTML5 is a general term for a number of emerging web technologies, including standardized rich media and interactivity. HTML5 can also be the basis for developing robust offline applications. For experienced web developers, using HTML5 is more attractive than learning a new compiled language, such as Objective-C or the Java™ language, but HTML5 applications have their own learning curve. This article describes how to successfully mix online content while providing a rich experience for users not connected to a network.

The sample application

This sample application is designed for use on a wide range of desktop and mobile devices. It provides a set of food and drink recipes. Three recipes are static and will be available to users when they're offline. When online, the application will be able to display a "recipe of the day," provided via a web service delivering content via Ajax.

Technology reuse is key to agile web development. This sample application uses two popular open source libraries:

  • jQuery— Robust cross-platform access to JavaScript and the DOM
  • jQTouch— Framework for HTML5 mobile applications using WebKit browsers

See Resources for more information about jQuery and jQTouch.

For best results, develop HTML5 applications using Apple Safari V4 or later, although Google Chrome may also work.

Using jQTouch

You can best manage jQTouch applications as single HTML documents. Each "page" in the application is a different HTML <div> with a unique id attribute. The basic outline of a jQTouch application looks like this:

  1. HTML header and imports
  2. Starting <div>
  3. Zero or more additional pages as <div>s with unique IDs

Setting up imports

The top of the sample application imports the CSS and JavaScript for the application. It also configures the HTML5 offline cache. Listing 1 provides the necessary code.

Listing 1. Headers necessary for jQTouch and HTML5 offline
<!DOCTYPE html>
<html manifest="sample.manifest">
  <head>
    <meta charset="utf-8" />
    <title>Sample recipe application</title>
    <style type="text/css">@import "jqtouch/jqtouch/jqtouch.min.css";</style>
    <style type="text/css">@import "jqtouch/themes/jqt/theme.min.css";</style>
    <style type="text/css">@import "sample.css";</style>
    <script src="jqtouch/jqtouch/jquery.1.3.2.min.js" 
            type="text/javascript"></script>
    <script src="jqtouch/jqtouch/jqtouch.min.js" 
            type="text/javascript"></script>
    <script src="sample.js" type="text/javascript"></script>
  </head>

Enabling HTML5

About the HTML5 markup

The simplified DOCTYPE may look strange to programmers familiar with DTDs and XML: Its only purpose is to trigger "standards mode" in web browsers. Because browsers never used DTD-based validation (due to the proliferation of "tag soup" HTML), there is no particular benefit to providing a rigorous DOCTYPE. If you build Web applications with XML-aware tools, you can still use the HTML V4.01 or XHTML V1.0 DOCTYPEs, but the document will not completely validate because of the HTML5 extensions.

Similarly, <meta charset="utf-8"> may look unfamiliar, but it is also valid HTML5. See Resources for a discussion about the simplified syntax in HTML5.

This sample application includes the ability to remain accessible while offline. That ability is enabled by including the manifest attribute. The value of this attribute must be the path to the cache manifest file, as demonstrated below:

<html manifest="sample.manifest">

The cache manifest typically contains two sets of resources:

  • A list of resources required to be cached for offline use
  • A list of resources that may only be available when the document is online

The syntax of the cache manifest is quite simple, as shown in Listing 2.

Listing 2. The cache manifest file for the sample application
CACHE MANIFEST

# This is a comment and will be ignored 

# Files specific to this application:
sample.js
sample.css

# Files that are a part of jQTouch:
# (See the sample code for a complete list)
jqtouch/jqtouch/jqtouch.min.css

NETWORK:
# These resources will be available only when online:
sample.json

The first line is alwaysCACHE MANIFEST. Each resource that may be offline — HTML pages, CSS, JavaScript, images, or any other kind of file — is listed on a new line. When the application is first accessed, the browser inspects the cache manifest, downloads all resources, and stores them for offline use.

Resources following the NETWORK: line are not cached and can be accessed only when the network is available. Although a file is listed here, you can use partial path names. For example, you could include /online/ here and set up the application such that all online-only resources fall under that path.

Forgetting to list all of the resources in the application as offline or online usually results in the whole application failing to be marked as offline-enabled. Other subtleties in the current implementations that can cause confusion include:

  • The web server must serve the manifest file as type text/cache-manifest.
  • The file pointing to the cache manifest (sample.html in this example) does not need to be listed.
  • Items listed in the manifest will only be reloaded when you modify the manifest itself, not when those resources change.
  • The web server should serve the manifest file with no-cache response headers.
  • If the web page references an unmanifested file, the application may not be cached for offline use. Often, this error is silent. In Safari V4 and later, check the Activity panel for any warnings.

If an HTML5 offline application is set up properly, it should be possible to access the application using a browser and server once, then turn off the server or local network access, refresh, and still be able to interact with the content. If the browser says the site cannot be reached, recheck the above list for configuration problems.


Developing with jQTouch

The jQTouch library requires several imports:

  • jqtouch.min.css.— The CSS for jQTouch itself
  • theme.min.css.— The CSS for the current theme (this example uses the default theme)
  • jquery.1.3.2.min.js or later— jQuery itself
  • jqtouch.min.js.— The jQTouch main script
  • samples.js.— Your custom JavaScript, which defines the unique functionality of this application

Mobile web performance tips

Following general web best practices, put JavaScript imports at the bottom of the HTML document, just before the close of the <body> tag. For clarity, this example puts them in the <head>.

Because mobile devices have high HTTP transactional overhead due to slow wireless connections, it is recommended that you combine multiple JavaScript files into a single library. You do this via an automated build/deployment; it is much easier for humans to develop using small, well-defined, discrete libraries.

Similarly, consider the use of CSS sprites in place of multiple images. Also, collapse stylesheets into single documents for deployment.

jQTouch content pages

Each page in a jQTouch application is actually just an HTML <div> that follows some conventions:

  • It must have a unique id attribute.
  • That ID should be linked somewhere in the application using a normal HTML anchor element.
  • The home page of the jQTouch application is the <div> that has the class value current.

The jQTouch library provides a number of methods to animate transitions from page to page. By default, it uses an attractive "swipe" transition using CSS3. On many WebKit implementations, these transitions are hardware-accelerated, which provides a naturalistic application-like feel. You can find links to these pages on the home page of the jQTouch application, as shown in Listing 3.

Listing 3. The home page, designated by the class named "current"
    <div id="home" class="current">
      <div class="toolbar">
        <h1>HTML5 Sample</h1>
      </div>
      <ul class="rounded">
        <li class="arrow"><a href="#recipe1">Breakfast Circles</a></li>
        <li class="arrow"><a href="#recipe2">Slowhand Jackson</a></li>
        <li class="arrow"><a href="#recipe3">Potato Chip Cookies</a></li>
        <li class="arrow online-required"><a href="#recipe4">Recipe of the Day</a></li>
      </ul>
    </div>

Most jQTouch pages consist of an outer <div> with its unique ID followed by a <div> with the attribute toolbar that contains the page title. Subsequent content is in the form of a list or additional paragraphs.

The rounded and arrow classes are all defined in the main jQTouch style. Depending on the theme installed, their appearance may change. This example uses the default black and gray theme, as shown in Figure 1.

Figure 1. The home page of the sample application
Screenshot of sample applicaiton home page with choice of recipes

The first three recipes are all static content defined in the same HTML5 page. They each have unique IDs — for example, recipe1. These IDs are used to target the new page from the home page, as shown here:

<a href="#recipe1">Breakfast Circles</a></li>

Listing 4 contains the source code for this first recipe. Figure 2 illustrates the HTML rendering.

Listing 4. Static content in a jQTouch application
    <div id="recipe1" class="recipe">
      <div class="toolbar">
        <h1>Breakfast Circles</h1>
        <a class="back" href="#">Back</a>
      </div>
      <ul class="rounded">
        <li>2C flour</li>
        <li>1/2C sugar</li>
        <li>1/2C confectioners sugar</li>
        <li>2T Earl Grey tea leaves (about 6 bags)</li>
        <li>1/2t salt</li>
        <li>1t vanilla</li>
        <li>1/2C butter</li>
        <li>Cold water</li>
      </ul>
      <p>
      Pulse dry ingredients in food processor to pulverize tea leaves. 
      Add vanilla, butter and pulse, adding as little water as 
      necessary to form loose dough. Divide into two 2" logs and roll 
      with parchment paper. Chill 30 min.</p>
      <p>
        Cut into 1/4"-thick wafers and bake at 375 degrees on parchment 
        until edges start to brown, about 12 min.
      </p>
    </div>

Note that this <div> contains one new class value: recipe. The default jQTouch stylesheets do not provide good style control over nested <p> elements, which are being used here for the recipe instructions. Because jQTouch is just a web application, you are free to add custom styling however you like using normal CSS.

In this case, the sample.css contains a few simple customizations, including div.recipe p { margin: 1em; } to provide an attractive margin for recipe instructions.

Figure 2. The home page of the sample application
Screenshot of the recipe for Breakfast Circles in the browser with a list of ingredients and instructions

All three static recipes will be available to offline users because their content is contained inside the HTML page. The next part of this article demonstrates how to mix online and offline content to create a flexible, extensible Web application that provides good offline capability.


Going online

The last recipe item in the list, shown in Listing 5, contains an additional HTML class: online-required.

Listing 5. An item only displayed when the user is online
<li class="arrow online-required">
  <a href="#recipe4">Recipe of the Day</a>
</li>

In the CSS customization layer for this application, .online-required is set to display: none. This means that by default, the application is assumed to be offline, and no online resources are shown.

How then does the application know when you're online? That code is found in the JavaScript customization script sample.js, shown in Listing 6.

Listing 6. JavaScript to manage online resources
/* Initialize jQTouch on startup. 
 [ See sample code for complete listing ] */

// Standard jQuery method to run code when the browser 
// has finished loading all resources
jQuery(document).ready(function () {
  
  // If online, show all online-only resources
  if (window.navigator.onLine) {
    jQuery('.online-required').show();
  }
  ...

HTML5 specifies a JavaScript API value window.navigator.onLine. When true, the browser is online and connected to a network. When offline, it can only access offline resources in the cache manifest. In this application, when the application is online, all DOM elements with the class online-required will be shown.

Testing window.navigator.onLine

In desktop Web browsers that do not support HTML5, the value of window.navigator.onLine is invariably true, even if the computer does not have a network connection. You will have to introduce a testing framework that can emulate the offline state or test using a mobile device only.

Accepting online data

An efficient method to populate a jQTouch application with online data is to provide skeleton pages to hold that data in advance. Listing 7 shows the <div> for the online-only recipe.

Listing 7. Placeholder jQTouch page for the online-only recipe
<div id="recipe4" class="recipe">
  <div class="toolbar">
    <h1>Recipe of the Day</h1>
    <a class="back" href="#">Back</a>
  </div>
  <!-- The recipe will be populated here -->
</div>

Now, in the custom JavaScript, you need an event handler to request the recipe and populate the HTML page with the results. The obvious approach would be to define an onclick handler for the #recipe4 ID.

However, jQTouch overrides the normal click behavior to accomplish its magic of moving from page to page. Instead, you can take advantage of the fact that CSS3 transitions fire start and end events. You can bind to these events using jQuery, even though the events are not native to jQuery. Following is the code:

jQuery('#recipe4').bind('pageAnimationStart', function () {
  ...
});

Not seeing the sliding transition or Ajax load?

As of this writing, only Safari versions 4 and 5 and Mobile Safari show the visual transition and fire the pageAnimationStart event. If you need to support other WebKit browsers, use a different event.

The pageAnimationStart event fires almost immediately after the click event. When the transition finishes, pageAnimationEnd fires. I prefer to associate most actions with the start event, as that gives the browser some time to collect the data while the user is watching the animation.

Populating data via Ajax

All that remains is some normal Ajax interaction. This example assumes that the result format will be JSON data. In this case, the data comes directly from a JSON file — sample.json, shown in Listing 8.

Listing 8. JSON data containing the recipe of the day
[ { "title" : "Doggie Delight", "ingredients" :  \
["1 cup dry kibble", "1 pound butter",  "1 beef bouillon cube", \
"2 tbsp oregano" ], "instructions": "Combine all ingredients in bowl.\
 Season to taste. Serve immediately." }]

Listing 9 contains the code to take this data and populate the placeholder <div>.

Listing 9. JSON data to populate the placeholder
jQuery.ajax({ url: "sample.json",
  success: function (data) {

    // Set the recipe title
    jQuery('#recipe4 h1').text(data[0].title);


    // Create a UL and add each recipe item to it
    var ul = jQuery('<ul class="rounded">');
    jQuery.each(data[0].ingredients, function (index, item) {
      jQuery('<li>').text(item).appendTo(ul);
    });

    // Add the ingredients list and the recipe instructions
    jQuery('#recipe4').append(ul).append(
      jQuery('<p>').text(data[0].instructions));

Figure 3 shows the final rendering of the dynamic data.

Figure 3. The dynamic recipe in a browser
Screenshot of the recipe for Breakfast Circles in the browser with a list of ingredients and instructions

Conclusion

More new mobile devices arrive on the market each day. While it's possible to develop custom native applications for each new platform and hardware, there's opportunity for small, agile teams to create cross-platform mobile web applications with similar performance characteristics. Whether as prototypes for larger native applications or as first-class sites themselves, mobile web applications are attractive for developers who already know HTML, JavaScript, and CSS.

The JavaScript APIs available in HTML5 mean that web apps have access to more hardware data than ever — not just network status but orientation, location, and other features. In many cases, these APIs already enjoy broad support in popular mobile browsers.

Web developers should not feel left behind in the rush to mobile application development. You may already have all the skills you need to develop for smartphones, netbooks, and tablets.


Download

DescriptionNameSize
Sample scriptsos-html5data-app-code-samples.zip4KB

Resources

Learn

  • Check out HTML5 to get a vocabulary and associated APIs for HTML and XHTML from the W3C.
  • Visit WebKit to learn more about the open source project and available WebKit browsers for many platforms.
  • Read Building iPhone Apps with HTML, CSS, and JavaScript for an excellent resource describing a number of techniques for mobile web application development.
  • Be sure to read Dive into HTML5 for deep analysis and practical code samples for HTML5 developers.
  • Learn more about the jQuery framework, indispensable for JavaScript development on all modern browsers, including mobile browsers.
  • The jQTouch library is designed for Apple iPhone web application development, but also works well on Android and webOS devices.
  • To listen to interesting interviews and discussions for software developers, check out developerWorks podcasts.
  • Stay current with developerWorks' Technical events and webcasts.
  • Follow developerWorks on Twitter.
  • Check out upcoming conferences, trade shows, webcasts, and other Events around the world that are of interest to IBM open source developers.
  • Visit the developerWorks Open source zone for extensive how-to information, tools, and project updates to help you develop with open source technologies and use them with IBM's products, as well as our most popular articles and tutorials.
  • The My developerWorks community is an example of a successful general community that covers a wide variety of topics.
  • Watch and learn about IBM and open source technologies and product functions with the no-cost developerWorks On demand demos.

Get products and technologies

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Open source on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=528279
ArticleTitle=Data-driven interactive applications with HTML5 and Ajax
publish-date=10052010