6. Step 6 - Implement the Update Use Case

Again, we have an HTML page for the user interface (updateBook.html) and a view code file (src/view/updateBook.js). The HTML form for the UI of the "update book" operation has a selection field for choosing the book to be updated, an output field for the standard identifier attribute isbn, and an input field for each attribute of the Book class that can be updated. Notice that by using an output field for the standard identifier attribute, we do not allow changing the standard identifier of an existing object.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Minimal JS Front-End App Example</title>
  <script src="src/ctrl/initialize.js"></script>
  <script src="src/model/Book.js"></script>
  <script src="src/view/updateBook.js"></script>
  <script>
   window.addEventListener("load", pl.view.updateBook.setupUserInterface);
  </script>
</head>
<body>
  <h1>Public Library: Update a book record</h1>
  <form id="Book" action="">
    <p>
      <label>Select book: 
        <select name="selectBook"><option value=""> --- </option></select>
      </label>
    </p>
    <p><label>ISBN: <output name="isbn" /></label></p>
    <p><label>Title: <input name="title" /></label></p>
    <p><label>Year: <input name="year" /></label></p>
    <p><button type="button" name="commit">Save Changes</button></p>
  </form>
  <nav><a href="index.html">Back to main menu</a></nav>
</body>
</html>

Notice that we include a kind of empty option element, with a value of "" and a display text of ---, as a default choice in the selectBook selection list element. So, by default, the selectBook form control's value is undefined, requiring the user to choose one of the available options for defining a value for this element.

The setupUserInterface procedure now has to populate the select element's option list by loading the collection of all book objects from the persistent data store and creating an option element for each book object:

pl.view.updateBook = {
  setupUserInterface: function () {
    var formEl = document.forms['Book'],
        saveButton = formEl.commit,
        selectBookEl = formEl.selectBook;
    var key="", keys=[], book=null, optionEl=null;
    // load all book objects
    Book.loadAll();
    // populate the selection list with books
    keys = Object.keys( Book.instances);
    for (i=0; i < keys.length; i++) {
      key = keys[i];
      book = Book.instances[key];
      optionEl = document.createElement("option");
      optionEl.text = book.title;
      optionEl.value = book.isbn;
      selectBookEl.add( optionEl, null);
    }
    // when a book is selected, populate the form with the book data
    selectBookEl.addEventListener("change", function () {
        var book=null, key = selectBookEl.value;
        if (key) {
          book = Book.instances[key];
          formEl.isbn.value = book.isbn;
          formEl.title.value = book.title;
          formEl.year.value = book.year;
        } else {
          formEl.reset();
        }
    });
    saveButton.addEventListener("click", 
        pl.view.updateBook.handleUpdateButtonClickEvent);
    window.addEventListener("beforeunload", function () {
        Book.saveAll(); 
    });
  },
  handleUpdateButtonClickEvent: function () {
    var formEl = document.forms['Book'];
    var slots = { isbn: formEl.isbn.value, 
        title: formEl.title.value, 
        year: formEl.year.value
    };
    Book.update( slots);
    formEl.reset();
  }
};