Contents


Data-driven interactive applications with HTML5 and Ajax

Cross-platform Web apps for online or offline use

Comments

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 Related topics 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

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

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
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
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.

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 () {
  ...
});

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
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.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

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