This is a simple demo of a todo app built using IndexedDB for storing todos.
You can learn how to build the app here: http://blog.teamtreehouse.com/create-your-own-to-do-app-with-html5-and-indexeddb
<div id="page-wrapper"> | |
<!-- Form for new Todo Items --> | |
<form id="new-todo-form" method="POST" action="#"> | |
<input type="text" name="new-todo" id="new-todo" placeholder="Enter a todo item..." required> | |
</form> | |
<!-- Todo Item List --> | |
<ul id="todo-items"></ul> | |
</div> |
/** | |
* @file A module for interacting with the DB. | |
* @author Matt West <matt.west@kojilabs.com> | |
* @license MIT {@link https://opensource.org/licenses/MIT}. | |
*/ | |
var todoDB = (function() { | |
var tDB = {}; | |
var datastore = null; | |
/** | |
* Open a connection to the datastore. | |
*/ | |
tDB.open = function(callback) { | |
// Database version. | |
var version = 1; | |
// Open a connection to the datastore. | |
var request = indexedDB.open('todos', version); | |
// Handle datastore upgrades. | |
request.onupgradeneeded = function(e) { | |
var db = e.target.result; | |
e.target.transaction.onerror = tDB.onerror; | |
// Delete the old datastore. | |
if (db.objectStoreNames.contains('todo')) { | |
db.deleteObjectStore('todo'); | |
} | |
// Create a new datastore. | |
var store = db.createObjectStore('todo', { | |
keyPath: 'timestamp' | |
}); | |
}; | |
// Handle successful datastore access. | |
request.onsuccess = function(e) { | |
// Get a reference to the DB. | |
datastore = e.target.result; | |
// Execute the callback. | |
callback(); | |
}; | |
// Handle errors when opening the datastore. | |
request.onerror = tDB.onerror; | |
}; | |
/** | |
* Fetch all of the todo items in the datastore. | |
* @param {function} callback A function that will be executed once the items | |
* have been retrieved. Will be passed a param with | |
* an array of the todo items. | |
*/ | |
tDB.fetchTodos = function(callback) { | |
var db = datastore; | |
var transaction = db.transaction(['todo'], 'readwrite'); | |
var objStore = transaction.objectStore('todo'); | |
var keyRange = IDBKeyRange.lowerBound(0); | |
var cursorRequest = objStore.openCursor(keyRange); | |
var todos = []; | |
transaction.oncomplete = function(e) { | |
// Execute the callback function. | |
callback(todos); | |
}; | |
cursorRequest.onsuccess = function(e) { | |
var result = e.target.result; | |
if (!!result == false) { | |
return; | |
} | |
todos.push(result.value); | |
result.continue(); | |
}; | |
cursorRequest.onerror = tDB.onerror; | |
}; | |
/** | |
* Create a new todo item. | |
* @param {string} text The todo item. | |
*/ | |
tDB.createTodo = function(text, callback) { | |
// Get a reference to the db. | |
var db = datastore; | |
// Initiate a new transaction. | |
var transaction = db.transaction(['todo'], 'readwrite'); | |
// Get the datastore. | |
var objStore = transaction.objectStore('todo'); | |
// Create a timestamp for the todo item. | |
var timestamp = new Date().getTime(); | |
// Create an object for the todo item. | |
var todo = { | |
'text': text, | |
'timestamp': timestamp | |
}; | |
// Create the datastore request. | |
var request = objStore.put(todo); | |
// Handle a successful datastore put. | |
request.onsuccess = function(e) { | |
// Execute the callback function. | |
callback(todo); | |
}; | |
// Handle errors. | |
request.onerror = tDB.onerror; | |
}; | |
/** | |
* Delete a todo item. | |
* @param {int} id The timestamp (id) of the todo item to be deleted. | |
* @param {function} callback A callback function that will be executed if the | |
* delete is successful. | |
*/ | |
tDB.deleteTodo = function(id, callback) { | |
var db = datastore; | |
var transaction = db.transaction(['todo'], 'readwrite'); | |
var objStore = transaction.objectStore('todo'); | |
var request = objStore.delete(id); | |
request.onsuccess = function(e) { | |
callback(); | |
} | |
request.onerror = function(e) { | |
console.log(e); | |
} | |
}; | |
// Export the tDB object. | |
return tDB; | |
}()); | |
/** | |
* @file The main logic for the Todo List App. | |
* @author Matt West <matt.west@kojilabs.com> | |
* @license MIT {@link https://opensource.org/licenses/MIT}. | |
*/ | |
window.onload = function() { | |
// Display the todo items. | |
todoDB.open(refreshTodos); | |
// Get references to the form elements. | |
var newTodoForm = document.getElementById('new-todo-form'); | |
var newTodoInput = document.getElementById('new-todo'); | |
// Handle new todo item form submissions. | |
newTodoForm.onsubmit = function() { | |
// Get the todo text. | |
var text = newTodoInput.value; | |
// Check to make sure the text is not blank (or just spaces). | |
if (text.replace(/ /g,'') != '') { | |
// Create the todo item. | |
todoDB.createTodo(text, function(todo) { | |
refreshTodos(); | |
}); | |
} | |
// Reset the input field. | |
newTodoInput.value = ''; | |
// Don't send the form. | |
return false; | |
}; | |
} | |
// Update the list of todo items. | |
function refreshTodos() { | |
todoDB.fetchTodos(function(todos) { | |
var todoList = document.getElementById('todo-items'); | |
todoList.innerHTML = ''; | |
for(var i = 0; i < todos.length; i++) { | |
// Read the todo items backwards (most recent first). | |
var todo = todos[(todos.length - 1 - i)]; | |
var li = document.createElement('li'); | |
var checkbox = document.createElement('input'); | |
checkbox.type = "checkbox"; | |
checkbox.className = "todo-checkbox"; | |
checkbox.setAttribute("data-id", todo.timestamp); | |
li.appendChild(checkbox); | |
var span = document.createElement('span'); | |
span.innerHTML = todo.text; | |
li.appendChild(span); | |
todoList.appendChild(li); | |
// Setup an event listener for the checkbox. | |
checkbox.addEventListener('click', function(e) { | |
var id = parseInt(e.target.getAttribute('data-id')); | |
todoDB.deleteTodo(id, refreshTodos); | |
}); | |
} | |
}); | |
} |
* { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } | |
body, html { | |
padding: 0; | |
margin: 0; | |
} | |
body { | |
font-family: Helvetica, Arial, sans-serif; | |
color: #545454; | |
background: #F7F7F7; | |
} | |
#page-wrapper { | |
width: 550px; | |
margin: 2.5em auto; | |
background: #FFF; | |
box-shadow: 0 1px 3px rgba(0,0,0,0.2); | |
border-radius: 3px; | |
} | |
#new-todo-form { | |
padding: 0.5em; | |
background: #0088CC; | |
border-top-left-radius: 3px; | |
border-top-right-radius: 3px; | |
} | |
#new-todo { | |
width: 100%; | |
padding: 0.5em; | |
font-size: 1em; | |
border-radius: 3px; | |
border: 0; | |
} | |
#todo-items { | |
list-style: none; | |
padding: 0.5em 1em; | |
margin: 0; | |
} | |
#todo-items li { | |
font-size: 0.9em; | |
padding: 0.5em; | |
background: #FFF; | |
border-bottom: 1px solid #EEE; | |
margin: 0.5em 0; | |
} | |
input[type="checkbox"] { | |
margin-right: 10px; | |
} |
This is a simple demo of a todo app built using IndexedDB for storing todos.
You can learn how to build the app here: http://blog.teamtreehouse.com/create-your-own-to-do-app-with-html5-and-indexeddb