top trim

"To-Do List" Übung 6.2: Den localStorage Dienst benutzen

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: 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.

Wichtig

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:

  1. 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;
    
  2. 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.

  3. 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();
    }
    
  4. 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();
      }
    }
    
  5. 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:

bottom trim