HTML5 includes two new ways to store data on the client – local stor­age and ses­sion stor­age. Local stor­age has no time limit on how long the data should be kept around, ses­sion stor­age on the other hand (as the name sug­gests) stores data for only one session.

Tra­di­tion­ally you can store data on the client using cook­ies, but they are not suited for stor­ing large amounts of data because every­thing gets sent back to the server on every request and hence slows down the roundtrip and mak­ing the user expe­ri­ence less enjoyable.

Using the new stor­age meth­ods, data is only passed on when asked for and it’s there­fore pos­si­ble to store large amounts of data with­out slow­ing down the site. The data is also sand­boxed and a web­site can only access data stored by itself, you can use javascript to set and get data from the rel­e­vant storage.

Browser Sup­port Detection

A browser that sup­ports HTML5’s local stor­age will have a local­Stor­age prop­erty on the global win­dow object, you can write your own func­tion to check for the exis­tence of and valid­ity (not null) of the local­Stor­age prop­erty, or use a third-party library like Mod­ern­izr.

Mod­ern­izr is an open source, light weight javascript library that detects sup­port for many HTML5 and CSS3 fea­tures, when it runs it cre­ates a global object called Mod­ern­izr. To check for local stor­age sup­port, all you need to do is to check the boolean flag for local storage:

if (Modernizr.localstorage) {
    // browser supports local storage
}
else {
    // browser doesn't support local storage
}

or sim­i­larly for ses­sion storage:

if (Modernizr.sessionstorage) {
    // browser supports local storage
}
else {
    // browser doesn't support local storage
}

API

The full API spec­i­fi­ca­tion for the local­Stor­age and ses­sion­Stor­age objects can be found here. At the time of writ­ing, this is how the com­mon Stor­age inter­face look:

image

Demo

I’ve put together a quick demo here to illus­trate how to detect and use the local and ses­sion stor­age to get, set, remove and clear stored items (well, basi­cally, cov­ers each of the avail­able meth­ods on the Stor­age inter­face above).

The page itself is sim­ple and crude, just a cou­ple of <div> and most impor­tantly two tables which I use to show all the key value pairs stored in the local and ses­sion storage:

image

Page Load

When the page fin­ishes load­ing, I call the Mod­ern­izr object to find out if the cur­rent browser sup­ports local and/or ses­sion stor­age, if not, hide the rel­e­vant <div> ele­ments so the tables are not even shown on the page:

$(document).ready(function () {
    // hide the storage divs if browser doesn't support local storage or session storage

    if (Modernizr.localstorage && Modernizr.sessionstorage) {
        $("#detectionSpan").html("Your browser supports both local and session storage");
    } else {
        if (!Modernizr.localstorage) {
            $("#detectionSpan").html("Your browser doesn't support local storage");
            $("#localStorageDiv").hide();
        } else {
            $("#detectionSpan").html("Your browser doesn't support session storage");
            $("#sessionStorageDiv").hide();
        }
    }
    showKeys();
});
Pop­u­late Tables

The showKeys() func­tion pop­u­lates the localTable and ses­sionTable tables with the keys in the cor­re­spond­ing stor­age if and only if the stor­age type is sup­ported by the browser:

// show the keys currently held in the local and session storage
function showKeys() {
    if (Modernizr.localstorage) {
        showStorageKeys("local", "#localTable");
    }
    if (Modernizr.sessionstorage) {
        showStorageKeys("session", "#sessionTable");
    }
}

// show the keys currently held in the specified type of storage in the specified table
function showStorageKeys(type, table) {
    // get the specified type of storage, i.e. local or session
    var storage = window[type + 'Storage'];

    // remove the rows in the specified table before we start
    $(table + " > tbody > tr").remove();

    // loop through the existing keys in the storage and add them to the TBODY element as rows
    for (var i = 0; i < storage.length; i++) {
        var key = storage.key(i);
        var value = storage.getItem(key);
        $(table + " > tbody:last")
            .append("<tr><td>" + key + "</td>" +
                    "<td>" + value + "</td>" +
                    "<td><input type='submit' value='Remove' onclick='removeItem(\"" + type + "\", \"" + key + "\")'/></td></tr>");
    }
}
Intro­duc­ing the new place­holder attribute

You might have noticed that the two text boxes had place­holder text sim­i­lar to that famil­iar search box in Firefox:

text boxes with place holder text Firefox search box

This is done using HTML5’s place­holder attribute for the <input> tag:

<input id="keyText" placeholder="Enter key"/>
<input id="valueText" placeholder="Enter value"/>

Nice and easy, eh? ;-)

Set­ting an item

To add a new key value pair or update the value asso­ci­ated with an exist­ing key, you just have to call the setItem method on the intended stor­age object:

// adds a new key to both local and session storage
function setKey() {
    var key = $("#keyText").val();
    var value = $("#valueText").val();

    if (Modernizr.localstorage) {
        localStorage.setItem(key, value);
    }
    if (Modernizr.sessionstorage) {
        sessionStorage.setItem(key, value);
    }
    showKeys();
}
Remov­ing an item

Ear­lier in the showStorageKeys(type, table) func­tion, I added a row to the rel­e­vant table for each key value pair in the stor­age includ­ing a but­ton with a han­dler for the onclick event. The han­dlers are cre­ated with the cor­rect stor­age type (“local” or “ses­sion”) and key for the cur­rent row baked in already so that they will call the removeItem(type, key) func­tion with the cor­rect parameters:

// removes an item with the specified key from the specified type of storage
function removeItem(type, key) {
    // get the specified type of storage, i.e. local or session
    var storage = window[type + 'Storage'];
    storage.removeItem(key);
    showKeys();
}
Clear­ing all items

Finally, the ’”Clear” but­tons under­neath the tables call the clear­LocalKeys() and clearS­es­sion­Keys() func­tion to remove all the key value pairs in the cor­re­spond­ing storage:

function clearLocalKeys() {
    clearKeys("local");
}

function clearSessionKeys() {
    clearKeys("session");
}

// clear all the held keys in the specified type of storage
function clearKeys(type) {
    // get the specified type of storage, i.e. local or session
    var storage = window[type + 'Storage'];

    // clear the keys
    storage.clear();

    showKeys();
}

So that cov­ers all the inter­est­ing bits about the demo and all and all pretty straight for­ward and easy to imple­ment, admit­tedly I’m a javascript novice so if you feel any of this could be done bet­ter please feel free to point out to me!

Share
  • Pingback: Having fun with HTML5 – contenteditable attribute | theburningmonk.com

  • Richard

    Thanks for the great demo. This would be per­fect for a project I’m work­ing on.

    How can I make it so that:

    a) the value is a textare­abox, instead of a input box
    b) a load but­ton next to the remove but­ton that pushes the value into the textarea?

    Thanks in advance

  • the­burn­ing­monk

    Hi Richard,

    I’ve used the local stor­age in another demo (http://stickynote.theburningmonk.com) where I’ve used textarea instead, the tech­nique is essen­tially the same with some minor changes, you can read more about it in another post here:
    http://theburningmonk.com/2011/01/creating-a-sticky-note-app-with-html5-css3-and-javascript/

    Cheeers,

  • Pingback: Punkchip | Maintaining the user journey with HTML 5 web storage

  • Tom Marrs

    Great Demo and code.

    I have a ques­tion about Ses­sion Stor­age. When I used the Stor­age Demo page on your site, both Local and Ses­sion Stor­age worked properly.

    But when I down­loaded your demo to my machine, Mod­ern­izr said that Ses­sion Stor­age wasn’t enabled on my browser. Is this due to the fact that I’m run­ning these pages offline (i.e., not from a server)?

  • vivek

    Can you help me by giv­ing a demo how to have an array of ses­sion­Stor­age variables

  • www.phpburn.com Klederosn Bueno

    Just improved it adding mul­ti­di­men­sional sup­port and depth search

    https://gist.github.com/3854049

    Tks for the tutorial

  • Richard Chung

    Dear Sir,
    Warmest Greet­ing,
    As fol­lowed is my sim­ple shop­ping cart, please kindly advise and guide me how to code html 5 ses­sion stor­age to store and dis­play­ing the cart as request;
    Thank you with Best regards
    Richard Chung
    __________________________________________________________________________________
    Please Help and re-coding of my request;
    1. how to insert code and ses­sion­Stor­age or local­stor­age state­ment at the array items includ­ing how to code setItem() and getitem() for sav­ing and dis­play­ing and for cart cal­cu­la­tion pur­pose.
    var items = new Array(); //create array to store items
    items[0] = new Array( “Com­puter”, 1500.00, 8 );
    items[1] = new Array( “Printer”, 500.00, 4.5 );
    items[2] = new Array( “Sofware”, 460.00, 0.0);

    2. How to saveitem() and getitem() of this.quantities[i] for fur­ther calculation

    func­tion Cart (holder, items) {
    this.holder = holder;
    this.items = items;
    this.quantities = Array();
    for (var i=0; i 0)
    this.quantities[index]–;

    5 how to use Table to dis­play the Cart result as fol­low;
    elm.innerHTML = “”+this.items[i][0]+“Quantity: “+this.quantities[i]+” “+this.total+” “+” “+this.grandtotal+” “+this.weight+” Total Weight “+this.totalweight+” “;

    6. Pos­si­ble the cus­tomer infor­ma­tion order form can be link­age with or insert­ing in the same ses­sion­stor­age cod­ing page or other sep­a­rated page. Please pro­vide your cod­ing example.

    ======================================================================

    The fol­low­ing my shop­ping cart code for your reference

    var cart;
    var items = new Array(); //create array to store items
    items[0] = new Array( “Com­puter”, 1500.00, 8 );
    items[1] = new Array( “Printer”, 500.00, 4.5 );
    items[2] = new Array( “Sofware”, 460.00, 0.0);

    func­tion addToCart(itemIndex) { //add to cart func­tion
    cart.add(itemIndex);
    cart.display();

    }
    func­tion removeItem(itemIndex) { //remove item from cart
    cart.remove(itemIndex);
    cart.display();
    alert(items[itemIndex] + ” has been removed from your cart!”);
    }
    func­tion Cart (holder, items) {
    this.holder = holder;
    this.items = items;
    this.quantities = Array();
    for (var i=0; i 0)
    this.quantities[index]–;
    }

    this.calculateItemTotal = func­tion( ) {
    var item­to­tal ;
    for ( i = 0; I < this.quantities.length ; I ++) {
    item­to­tal = items[i][1] * this.quantities [i];
    }
    return item­to­tal;
    }

    this.display = func­tion () {
    this.holder.innerHTML = “”; this.grandtotal = 0 ; this.totalweight = 0 ;

    for (var i=0; i 0) {

    this.total = ( this.items[i][1] * this.quantities[i] );
    this.weight = ( this.items[i][2] * this.quantities[i] );
    this.grandtotal = ( this.grandtotal + this.total );
    this.totalweight = (this.totalweight + this.weight );
    var elm = document.createElement(‘div’);
    elm.innerHTML = “”+this.items[i][0]+“Quantity: “+this.quantities[i]+” “+this.total+” “+” “+this.grandtotal+” “+this.weight+” Total Weight “+this.totalweight+” “;
    this.holder.insertBefore(elm, null);
    this.holder.insertBefore(elm, null);
    };

    }
    }
    }

    Shop­ping Cart:

    Add Cpm­puter
      
    Delete Computer

    Add Printer
      
    Delete Printer

    Add Soft­ware
      
    Delete Sofware

    cart = new Cart(document.getElementById(‘right’), items);