In this exercise, you will use the localStorage
service to provide persistent storage of ‘to-do" list items. Upon completion of the exercise, if you open your application, add new items, close and then reopen it, the items you previously created will still be available.
To complete the exercise, follow these steps:
Step 1: Create common JavaScript functions - In the common.js
file, create the generateKey
function; this function will be used to create unique keys for items stored in the localStorage
service.
Step 2: Modify the ToDoList gadget to include common.js - Make the generateKey
function available to the ToDoList
gadget by including common.js
in the gadget.
Step 3: Modify the ToDoList JavaScript functions - Modify the ToDoList JavaScript functions to save, delete, and retrieve items using the localStorage
service.
Step 4: Testing the application - Run you application, create one or more "to-do" items, close the application and then reopen it; verify that the previously created items are still available.
Step 1: Creating common JavaScript functions
The first function needed in this exercise is the generateKey
function, a function that creates a unique key for an item. Because this function is potentially of use to many gadgets, it should reside in the common.js
file.
You can create the generateKey
function on your own using the code shown below. Or, to save time, you can use the function provided in the common.js
exercise file, which is located in the ToDoList/common
directory.
If you have not yet downloaded the "To-Do List" exercise files, refer to the Downloaden erforderlicher Übungsdateien section in the introduction of this guide.
The generateKey
function is shown here:
// Declare gAppKey property at the beginning of the file var gAppKey = "todoList"; // Add the following function function generateKey(item) { if (typeof item == "undefined" || item == null || typeof item["date"] == "undefined" || item["date"] == null) { return ""; } var key = new Date(item["date"]); key = gAppKey + "." + key.getTime(); return key; }
Step 2: Modifying the ToDoList gadget to include common.js
Next, to make the functions in common.js
available to the ToDoList
gadget, you must edit ToDoList.box
, adding the code shown below in bold:
<gadget id="ToDoList" language="jscript"
code="ToDoList.js" >
<script id="common" language="jscript"
href="../../common/common.js"/>
<parts>
<box:titleArea id="titleArea"/>
<box:noteArea id="noteArea"/>
<box:buttonsArea id="buttonsArea"/>
</parts>
<behavior>
<reaction event="initialized" action="gadget:onInitialized();" />
</behavior>
</gadget>
Step 3: Modifying the ToDoList JavaScript functions
Now, you need to modify the ToDoList
JavaScript functions to save, delete, and retrieve items using the localStorage
service.
To do so, open the ToDoList.js
file and make the following modifications:
First, beneath the component
declaration in the ToDoList.js
file, add a reference to the keyDatabase
service, as shown below in bold.
// The component function is called when the gadget is first instantiated
function component (_gadget) { }
// reference to the keyDatabase service
component.prototype.keyDatabase = null;
Edit the insertItem
function to prepare the key and value pair that represent the "to-do" item and then insert it into the keyDatabase
service. Use the code shown below in bold.
component.prototype.insertItem = function (item)
{
// Prepare the key and value pair for the keyDatabase
var key = generateKey(item);
var value = item["date"] + "|" + item["title"] + "|" +
item["description"] + "|" + item["image"];
// Save the key and value pair that represents the item to the
// keyDatabase
if (key != "")
{
this.keyDatabase.setValueForKey(key, value);
}
this.items.push(item);
this.currentItem = this.items.length - 1;
this.displayCurrentItem();
}
The setValueForKey method inserts a new record with the specified key and value. If the key already exists, it updates the value for the specified key.
Edit the deleteItem
function to remove the item from the database.
component.prototype.deleteItem = function (index)
{
if (this.items == null || this.items[index] == null) { return; }
var key = generateKey(this.items[index]);
if (key != "")
{
// Remove this item from the keyDatabase
this.keyDatabase.removeKey(key);
}
this.items.splice(index, 1);
this.displayCurrentItem();
}
Edit the onInitialized
function: replace the this.displayDefaultItem
statement that was originally in the function with the try/catch
statement shown below in bold. This statement uses the createKeyDatabaseForAllIdentities
function to return a local storage mechanism that is public to all machine users.
// called when the gadget is created, but not yet presented (i.e. visible)
component.prototype.onInitialized = function ()
{
// get each part of the gadget by their respective id attributes
this.titleArea = this._gadget.getPartById("titleArea");
this.noteArea = this._gadget.getPartById("noteArea");
this.buttonsArea = this._gadget.getPartById("buttonsArea");
try
{
var factoryObj = shell.serviceManager.localStorage.factory;
this.keyDatabase = factoryObj.createKeyDatabaseForAllIdentities(gAppKey);
this.loadItemsFromKeyDatabase();
this.displayItem(0);
}
catch (e)
{
this.displayDefaultItem();
}
}
Now, create a new function called loadItemFromKeyDatabase
. This function iterates through all records in the localStorage service and pushes them onto the items
array.
component.prototype.loadItemsFromKeyDatabase = function () { var allKeys; if (this.keyDatabase) { allKeys = this.keyDatabase.listKeysWithPrefix(gAppKey); } if (allKeys) { for (var i = 0; i < allKeys.count; i++) { var key = allKeys.getValue(i); if (this.keyDatabase.keyExists(key)) { var item = Object(); var value = this.keyDatabase.getValueForKey(key); // each value is separated by a pipe '|' var values = value.split("|"); if (values.length < 4) { continue; } item["date"] = values[0]; item["title"] = values[1]; item["description"] = values[2]; item["image"] = values[3]; // push onto the items array this.items.push(item); } } } }
Notice the getValueForKey function shown above. This function retrieves a value in the localStorage mechanism based on the key that is passed as a parameter to the function.
Step 4: Testing the application
Test your application using the following scenarios:
Test Scenario 1: Open the application and create two "to-do" items. Close the application and then reopen it. The two items you previously created should continue to be available in the new session.
Test Scenario 2: Open the application and delete a "to-do" item. Close the application and then reopen it. The item you deleted should no longer be available.