Programming the Mobile Web : HTML 5 (part 4) - Client Storage

1/24/2011 4:28:02 PM

7. Client Storage

Working offline is great, but there’s a problem: where should a web application store vital statistics and other information when the device is not connected to the Internet? And if the device is not connected to the Internet, how can our applications access helpful databases or information? Client storage solutions come to our assistance, in two flavors: key/value storage and SQL databases (yes, from JavaScript, without server interaction).

Of course, we also have cookies, but they are simpler (only string storage), and we know they are not guaranteed to survive in the browser.

7.1. Key/value storage

HTML 5 defines a key/value store through two objects: localStorage and sessionStorage. They are pretty much the same, but the scopes are different: while the local store is used for long-term storage, the session store doesn’t persist after the user closes the tab or window.


We should use try/catch blocks when saving items, in case problems occur with the storage or the maximum available space is exceeded.

Both stores are used in the same way:

// Save an object or variable in the store
localStorage.setItem("name_in_the_storage", object_to_store);

// Read an object from the store
var object = localStorage.getItem("name_in_the_storage");

We can also delete all the objects using clear or delete one key using removeItem. There is also a storage event that we can listen for with window.addEventListener that will be fired when the contents of the local or session stores have changed.

7.2. SQL database

Having a relational database available in JavaScript sounds powerful. The main method that defines the availability of the JavaScript SQL database is the window.openDatabase method. This method has the following signature:

var db = window.openDatabase(shortName, version, displayName, sizeExpectable);

If we use a try/catch, we can capture errors during the operation. This method opens the database if it exists and creates it if it is the first time we’ve used it. To execute non-recordset sentences (CREATE TABLE, INSERT, etc.) we can use a transaction using the transact method, which receives a function as parameter. As a transaction, if one sentence fails, the others will not execute:
db.transact(function(t)) {
AUTOINCREMENT, name TEXT NOT NULL)', [], function() {}, errorHandler);

The array parameter after the query string is an array of parameters to be replaced in the query (using ? inside), the next parameter is the data handler function (not used in a non-recordset query), and the last parameter is a function handler for errors in the query.


HTML 5 doesn’t define which database engine should be used. Mobile browsers use SQLite, the open source database engine, so check the SQLite documentation for data type and SQL syntax support.

To create a typical SELECT statement with recordset looping, we can use the following template:

db.transact(function(t)) {
t.executeSql('SELECT * FROM countries', [], countriesHandler, errorHandler);

function countriesHandler(transaction, data) {
var record;
var id;
var name;
for (var i=0; i<data.rows.length; i++) {
// We get the current record
record = data.rows[i];
id = record['id'];
name = record['name'];
// Do something with record information

function errorHandler(transaction, error) {
alert('Error getting results');


JavaScript databases support versioning, allowing us to change schema on newer versions of our applications and detect what the current version installed on the client is, to create a migration procedure.

If you were working offline you should implement a synchronization method, using Ajax to download changes from and upload them to the server.


Safari on iOS accepts up to 5 MB in offline storage without user intervention. If you try to save more than 5 MB, the user will need to approve it (an automatic alert will appear).

7.2.1. Gears storage

Google Gears ( is an open source project that enhances web browsers and JavaScript with more functionality, much of which is part of the HTML 5 draft. Android 1.X supports only Gears, and we can also use SQL databases with Gears. The normal usage is simple and synchronous, as the following sample demonstrates:

<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript">
var db = google.gears.factory.create('beta.database');'countries');
name TEXT NOT NULL)');

var rs = db.execute('SELECT * FROM countries');

while (rs.isValidRow()) {
var id = rs.field(0);
var name = rs.field(1));
// Do something;

Fortunately, Google is working on an open source project that gives us an abstraction layer for both HTML 5 databases and Gears databases using the same code. The project is called the Web Storage Portability Layer and it is available at


Safari on iOS allows you to view stored databases and delete them from the device using SettingsSafariDatabases.

With this new layer, we can use the following code for select queries in both frameworks:

var database = google.wspl.DatabaseFactory.createDatabase('countries',
var statement = google.wspl.Statement('SELECT * FROM countries;');

database.createTransaction(function(tx) {
tx.executeAll([statement], {onSuccess: function(tx, resultSet) {
// Statement succeeded

for(; resultSet.isValidRow(); {
var id = resultSet.getRow()['id'];
var name = resultSet.getRow()['name'];
}, onFailure: function(error) {
// Statement failed
}, {onSuccess: function() {
// After transaction commits, before any other starts
}, onFailure: function(error) {
// After transaction fails, before any other starts

7.3. Client JSON store

Prepared for mobile devices, Lawnchair is a local client JSON store that uses HTML 5 features behind a very simple API. You can download the library from

To create a store, we just use code like this:

var countries = new Lawnhair('countries');

Then, we can save an object synchronously:{id: 5, name: 'Spain'});
// Object saved

or asynchronously:{id: 5, name: 'Spain'}, function() {
// Object saved

We can also save it using a key/value mechanism for easy retrieval:{key: 5, value: 'Spain'});

var spain = countries.get(5);

And we can easily get all the documents using:

countries.all(function(country) {
// We receive every country in this function

We can also remove documents, clear all the storage, and create iterators for easy filtering.

Web Compatibility Test

In 2010, the W3C created a test to score mobile browsers in terms of their RIA, Ajax, and HTML 5 support. The Web Compatibility Test for Mobile Browsers, available at, verifies compatibility with Ajax, the canvas HTML tag, the contenteditablevideo and audio HTML 5 tags, Web Workers, local storage, session storage, and @font-face. There are currently no mobile browsers that score 100%. attribute, geolocation, HTML 5 input forms, the offline AppCache, the

Some results are:

  • iPhone 3.0: 83%

  • Firefox 3.5 for Maemo: 83%

  • Bada Browser: 75%

  • Android 1.6–2.1: 67%

  • Opera: 33%

  • Symbian 5th edition: 17%

  • webOS: 17%

  • NetFront 3.5: 8.33%

  •  Windows Phone 7 : Submitting Your First Windows Phone Application to the Windows Phone Marketplace
  •  Windows Phone 7 : Packaging, Publishing, and Managing Applications
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 3)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 2)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 1)
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 2) - JavaScript Mobile UI Patterns
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 1) - JavaScript UI Libraries
  •  Windows Mobile Security - Kernel Architecture
  •  Windows Mobile Security - Introduction to the Platform
  •  iPhone Programming : Table-View-Based Applications - Building a Model
    Most View
    Improve Your TV Sound
    Droid RAZR HD And RAZR MAXX HD Smartphones Review (Part 3)
    Asus PadFone 2 - The Attraction Of The Phone-In-Tablet Combination (Part 4)
    Advanced Compacts - Pocket Power House (Part 1) : Canon Powershot G15, Fujifilm XF1
    The Jaguar F-Tpye R Coupe – The Cat’s Coupe
    Windows Server 2003 : Configuring Zone Properties and Transfers (part 2)
    The Best Mobile Apps (Part 1) - BBM
    Patriot Gauntlet Node - BYO Media Streamer
    Nexus 10 - A Worthy Challenger To The iPad
    Wireless Connections: What You Need To Know (Part 3)
    - First look: Apple Watch

    - 10 Amazing Tools You Should Be Using with Dropbox
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
    Top 10
    OPEL MERIVA : Making a grand entrance
    FORD MONDEO 2.0 ECOBOOST : Modern Mondeo
    BMW 650i COUPE : Sexy retooling of BMW's 6-series
    BMW 120d; M135i - Finely tuned
    PHP Tutorials : Storing Images in MySQL with PHP (part 2) - Creating the HTML, Inserting the Image into MySQL
    PHP Tutorials : Storing Images in MySQL with PHP (part 1) - Why store binary files in MySQL using PHP?
    Java Tutorials : Nested For Loop (part 2) - Program to create a Two-Dimensional Array
    Java Tutorials : Nested For Loop (part 1)
    C# Tutorial: Reading and Writing XML Files (part 2) - Reading XML Files
    C# Tutorial: Reading and Writing XML Files (part 1) - Writing XML Files