OFFLINE WEB APPLICATIONS - A SIMPLE START TO JQUERY, JAVASCRIPT, AND HTML5 FOR BEGINNERS (2014

A SIMPLE START TO JQUERY, JAVASCRIPT, AND HTML5 FOR BEGINNERS (2014)

CHAPTER 11: OFFLINE WEB APPLICATIONS

The previous chapter discussed storage, which is one of the most used offline application. However, in some scenarios, you may require better tools and advanced features like indexing, asynchronous support and handling transactions. These features are a part of the many other offline applications that are available.

This chapter discusses Websql and IndexedDB, which are relational constructs for data storage. However, they cannot be used for storing files. Therefore, FileSystem API is used for this purpose. The chapter ends with a discussion on how you can make your website offline-friendly using HTTP Cache.

Web SQL

Web SQL is a relational database and its most recent implementations are created on SQLite. However, it is important to mention that this database constrict is no longer supported by W3C yet it is still supported by many browsers.

How to Create and Open Database

A database can be created and opened using the following syntax:

var dbase = openDatabase('Lib', '1.0', 'Sample library', 5 * 1024 * 1024);

The parameters are as follows:

● name

● version

● displayName

● estimatedSize

● creationCallback

How to Manipulate Database

Manipulation scripts in SQL can be given as parameter to the transaction.executeSql() function for manipulating the database. An example of how a table can be created is given below:

transaction.executeSql("CREATE TABLE IF NOT EXISTS employees(" +

"id INTEGER PRIMARY KEY AUTOINCREMENT, " +

"fName TEXT, "+

"lName TEXT, " +

)");

IndexedDB

Till now, you have dealt with the two extreme cases of storing data over the web. While the web storage mechanisms follows the simple key-value pair model, Web SQL is based on the relational database model. IndexedDB is an alternative model that lies somewhere in between these two models. It is capable of dealing with everything from strings to complex objects. However, while using this storage mechanism, use browser-independent methods.

A database can be opened or created in the following manner:

var indexedDB = window.indexedDB;

var openRequest = indexedDB.open('Lib', 1);

An important facet of IndexedDB object is the keypath property, which is used to define the attributes that must be used as the key. If the specified property does not exist, then an auto-incrementing or auto-decrementing attribute can be created.

Indexes can be added using the following code:

var openRequest = indexedDB.open('Lib', 2);

openRequest.onupgradeneeded = function(response) {

var store = response.currentTarget.transaction.objectStore("employees");

store.createIndex('lName', 'lName', { unique: false });

};

The parameters required are: Name, keypath and optional parameters. In a similar manner, indexes can be removed using the following code:

store.deleteIndex('lastName');

You can add and remove object stores storing the following code:

var openRequest = indexedDB.open('Lib', 3);

openRequest.onupgradeneeded = function(response) {

response.currentTarget.result.deleteObjectStore("employees");

};

Similarly, an object can be added in the following manner:

response.currentTarget.result.createObjectStore("employees", { keypath: 'email' });

The next set of operations include transactions, which are performed in the following manner:

1. A transaction has to be opened in the following manner:

var newTrans = dbase.transaction(['employees', 'payroll']);

2. You can add a new record in the following manner:

var openRequest = indexedDB.open('Lib', 1);

var dbase;

openRequest.onsuccess = function(response) {

dbase = openRequest.result;

addEmployee();

};

function addEmployee() {

var myTrans = dbase.transaction('employees', 'readwrite');

var employees = myTrans.objectStore("employees");

var request = employees.add({fName: 'Sammy', lName: 'Carnie'});

request.onsuccess = function(response) {

alert('ID of New Record = ' + request.result);

};

request.onerror = function(response);

}

3. A record can be updated in the following manner:

var openRequest = indexedDB.open('Lib', 1);

var dbase;

openRequest.onsuccess = function(response) {

dbase = openRequest.result;

updateEmployee();

};

function updateEmployee() {

var myTrans = dbase.transaction('employees', 'readwrite');

var employees = myTrans.objectStore("employees");

var request = employeess.put({fName: 'Sammy', lName: 'Carnie'}, 1);

request.onsuccess = function(response) {

alert('ID of Updated Record = ' + request.result);

};

request.onerror = function(response);

}

4. You can delete a record using the following code:

function deleteEmployee() {

var myTrans = dbase.transaction('authors', 'readwrite');

var employees = myTrans.objectStore("employees");

var request = employees.delete(1);

request.onsuccess = function(response);

request.onerror = function(response);

}

How to Work with FileSystem API

The above mentioned storage mechanisms can be used for storing data, which is in form of strings. However, complex data structures like files and images may also be stored using URIs. However, it is an excessively costly option. HTML5 offers a low cost and simpler option called FileSystem API for this purpose. Using this format, you can create files and directories on a user file system’s sandboxed location.

The functionalities available include:

1. A FileSystem can be opened and created using:.

window.requestFileSystem(TEMPORARY, 5 * 1024 * 1024, getFile, handleError);

function getFile(fileSystem) {

fileSystem.root.getFile("sample.txt", { create: true }, fileOpened, handleError);

}

function fileOpened(fileEntry) {

alert("File opened!");

}

function handleError(error) {

alert(error.code);

}

The parameters for the requestFileSystem() function are type, size, successCallback and errorCallback. On the other hand, the parameter for getFile() function are path and options.

2. You can write to a file using the following code:

function writeToFile(fileWriter) {

fileWriter.onwriteend = function() { alert('Success'); };

fileWriter.onerror = function() { alert('Failed'); };

fileWriter.write(new Blob(['Hello world'], {type: 'text/plain'}));

}

You can append to a file using the following code:

function writeToFile(fileWriter) {

fileWriter.onwriteend = function() { alert('Success'); };

fileWriter.onerror = function() { alert('Failed'); };

fileWriter.seek(fileWriter.length);

fileWriter.write(new Blob(['Hello world'], {type: 'text/plain'}));

}

3. You can read from a file using the following code:

function readFile(file) {

var fileReader = new FileReader();

fileReader.onloadend = function() { alert(this.result); };

fileReader.onerror = function() { alert('Failed'); };

fileReader.readAsText(file);

}

4. You can delete a file using the following code:

fileEntry.remove(fileRemoved, handleError);

Similar functions exist for directories as well.