Skip to main content Link Menu Expand (external link) Document Search Copy Copied

To-Do Example

Our initial JavaScript example that models a to-do application. This example is slightly modified to save the user’s todo list to localStorage when the user leaves the page and then loads it back when the user returns to the page.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">  
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="CS4640 To-Do List">
  <meta name="description" content="An example to-do list using DOM manipulation">  
    
  <title>My To-do Items</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"  integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"  crossorigin="anonymous"> 

  <script>

    // Maintain an array of the todos that are on the
    // page so that we can more easily save them when
    // the page is unloaded
    var todos = [];

    /**
     * Add a to-do item to the website
     */
    function addTodo() {
        var item = document.getElementById("item");

        // add the new todo to the array
        todos.push(item.value);
        // separate out the DOM update
        drawTodo(item.value);

        // Clear the text box
        item.value = "";
    }

    /**
     * Add to the DOM just like before
     */
    function drawTodo(todoItem) {
        var table = document.getElementById("todos");

        var newRow = table.insertRow(table.rows.length);
        var newCell = newRow.insertCell(0);
        newCell.textContent = todoItem;
        newCell = newRow.insertCell(1);
        newCell.innerHTML = "<button class='btn btn-danger' onclick='removeTodo();'>Done</button>";

        newRow.onmouseover = function() {
            table.clickedRow = this.rowIndex;
        }
    }

    /**
     * Remove a to-do item.  NOTE: This does NOT remove them
     * from our array!  How could we modify this code so that
     * we actually do the right thing? (Try on your own)
     */
    function removeTodo() {
        var table = document.getElementById("todos");
        table.deleteRow(table.clickedRow);
    }

    /**
     * Save the array of todos as a JSON object to local storage
     * on the client.
     */
    function saveTodos() {
        localStorage.setItem("todolist", JSON.stringify(todos));
    }


    /**
     * Load the todos from local storage as a JSON object, if the
     * value was in local storage.  Modify the DOM to add each of
     * the to do items from the array in local storage.
     */
    function loadTodos() {
        var todoString = localStorage.getItem("todolist");
        if (todoString != null) {
            todos = JSON.parse(todoString);
        
            for (let i = 0; i < todos.length; i++) {
              drawTodo(todos[i]);
            }
        }
    }

    
  </script>
</head>

<!-- Add event handlers to the body on load and unload -->
<body onload="loadTodos();" onunload="saveTodos();">

    <div class="container">
        <div class="row">
        <form name="todo-add">
            <h1>My To Do List</h1>
            <label for="item" class="form-label">Item: </label>
            <div class="input-group">
                <input type="text" class="form-control" placeholder="To-Do Item" autofocus id="item" name="item"/>
                <input type="button" class="btn btn-primary" value="Add Item" onclick="addTodo();"/>            
            </div>
        </form>
    
        </div>
        <div class="row" style="margin-top: 20px;">    
            <div class="col-12">
    
                <table id="todos" class="table table-striped">
                    <tr class="table-dark">
                        <th style="width: 80%;">Item</th>
                        <th style="width: 20%;">Operation</th>
                    </tr>
                </table>
    
            </div>
        </div>
    </div>
 
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>