August 5, 2011

HTML 5 Experiments... Adventures in JavaScript

I've just been playing around doing a little R&D to look into the possibility of creating an HTML 5 application, with local storage and offline capabilities, being served up by Salesforce. It's taken me a little over two hours to get to the point where I can view a list of contacts on my phone from Salesforce, put the phone into flight mode, load the page again and retrieve the list from local storage. Obviously the first step was to grab myself a shiny new Developer Edition org, and then I chose the easy route of enabling sites so I could host the intended pages publicly to avoid login hassles etc..

I'm not going to throw down everything here, but essentially I expose data through a Visualforce page serving up JSON—I should look into the REST API, but that's fun for another day:

<apex:page controller="QQueryRunner" action="{!Init}" sidebar="false" showHeader="false" cache="false" contentType="text/javascript"> 
  {!mp_strJSON} 
</apex:page>

That data gets pulled using jQuery's getJSON() method and then processed and displayed, the script also uses local storage to save the data, though you have to do this a record and a field at a time using the basic setup (or use your own serialising). In its base form HTML 5 local storage uses key-value pairs, so I took the quick route for now:

for(contact in data.contacts) 
{ 
    var c = data.contacts[contact]; 
    localStorage["contact" + contact + "firstName"] = c.firstName; 
    // etc. :)

Using this and a similar loading mechanism I could pull the contacts from Salesforce, store them and then recall them again from the local storage area; the next step was that for offline I had to include a manifest file... I'm sure I've not set it up 100% right yet (haven't delved too deep into the network section which should be used for the data source), but hey, it works and that'll do for me on a Friday afternoon. Getting the manifest file into the page required me to break from the norm and include <html> tags myself so that I could specify the manifest file to use:

<apex:page controller="QVFC_AppHome" standardStylesheets="false" sidebar="false" showHeader="false" contentType="text/html" cache="true"> 
  <apex:outputText escape="false" value="{!"<!DOCTYPE html>"}"/> 
  <html manifest="/OfflineAppCache">

But what about the manifest itself? It's simply another publicly available Visualforce page hosted on the site, but with a specific content type as you can see below. The bare-bones manifest lists which files form the site and thus need to be saved by the browser to render the site offline.

<apex:page contentType="text/cache-manifest" showHeader="false" sidebar="false" cache="false"> 
CACHE MANIFEST 
/OfflineTest/AppHome 
/OfflineTest/Query 
/{!$Resource.JQuery} 
</apex:page>

Clearly just throwing these snippets into a few files isn't going to get you a working application, but it does give you the core building blocks to hook together, feel free to post any questions in the comments!