Created
June 24, 2011 22:34
-
-
Save greenido/1045816 to your computer and use it in GitHub Desktop.
IndexDB demo for MDC day (Chrome 12+ and FF4+)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>IndexDB Demo - Version 1.1</title> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |
<meta name="author" content="Ido Green"/> | |
</head> | |
<style> | |
#footer { | |
background-color: yellowgreen; | |
padding: 8px; | |
margin: 6px; | |
-moz-border-radius: 15px; | |
-webkit-border-radius: 15px; | |
} | |
#footer p { | |
font-size: 90%; | |
font-style: italic; | |
} | |
pre { | |
background-color: lightcyan; | |
padding: 8px; | |
margin: 6px; | |
-moz-border-radius: 15px; | |
-webkit-border-radius: 15px; | |
font-size: 20px; | |
} | |
#ourList { | |
background-color: lightgoldenrodyellow; | |
padding: 8px; | |
margin: 6px; | |
-moz-border-radius: 15px; | |
-webkit-border-radius: 15px; | |
} | |
</style> | |
<body> | |
<!-- | |
* MDC - fixit day | |
* Ido Green | |
* Date: 6/24/2011 | |
* | |
--> | |
<h1>Indexed DB: Demo</h1> | |
<aside class="note"> | |
<section> | |
This demo requires FF4 or Google Chrome 12 or greater. | |
</section> | |
</aside> | |
<section> | |
<pre>var idbRequest = window.<b>indexedDB</b>.<b>open</b>('Database Name'); | |
idbRequest.onsuccess = function(e) { | |
<b>var db = this.result</b>; | |
var transaction = db.<b>transaction</b>(idb_.objectStoreNames, <b>IDBTransaction.READ_ONLY</b>); | |
var curRequest = transaction.<b>objectStore</b>('ObjectStore Name').<b>openCursor</b>(); | |
curRequest.<b>onsuccess</b> = ...; | |
}; | |
</pre> | |
<div class="hcenter" id="indexeddb-example"> | |
<p> | |
<button onclick="indexedDbUtil.idbCreate()">Create object Store</button> | |
<button onclick="indexedDbUtil.idbRemove()">Remove object Store</button> | |
<button onclick="indexedDbUtil.showAll()">Show All objects</button> | |
</p> | |
<input type="text" placeholder="key" id="idb-key" size="10" /> <input type="text" placeholder="value" id="idb-value" size="10" /> | |
<button onclick="indexedDbUtil.idbSet()">set</button> | |
<div id="idb-log"></div> | |
<div class="record-list" id="idb-results-wrapper"></div> | |
<p> | |
<div id='ourList'> | |
</div> | |
</p> | |
</div> | |
<script> | |
// For our demo - let's put all the code under indexDBUti | |
var indexedDbUtil = (function() { | |
var idb_; // Our local DB | |
var idbRequest_; // Our DB request obj | |
// | |
// just a simple way to show what we are doing on the page | |
var idbLog_ = document.getElementById('idb-log'); | |
var idResultsWrapper_ = document.getElementById('idb-results-wrapper'); | |
// IndexedDB spec is still evolving - see: http://www.w3.org/TR/IndexedDB/ | |
// various browsers keep it | |
// behind various flags and implementation varies. | |
if ('webkitIndexedDB' in window) { | |
window.indexedDB = window.webkitIndexedDB; | |
window.IDBTransaction = window.webkitIDBTransaction; | |
} else if ('mozIndexedDB' in window) { | |
window.indexedDB = window.mozIndexedDB; | |
} | |
// Open our IndexedDB if the browser supports it. | |
if (window.indexedDB) { | |
idbRequest_ = window.indexedDB.open("Test", "Our Amazing test object IndexDB"); | |
idbRequest_.onerror = idbError_; | |
idbRequest_.addEventListener('success', function(e) { | |
// FF4 requires e.result. IDBRequest.request isn't set | |
// FF5/Chrome works fine. | |
idb_ = idbRequest_.result || e.result; | |
idbShow_(e); | |
}, false); | |
} | |
// on errors - show us what is going wrong | |
function idbError_(e) { | |
idbLog_.innerHTML += '<p class="error">Error: ' + | |
e.message + ' (' + e.code + ')</p>'; | |
} | |
// In cases we add/remove objects - show the user what is changing in the DB | |
function idbShow_(e) { | |
if (!idb_.objectStoreNames.contains('myObjectStore')) { | |
idbLog_.innerHTML = "<p>Object store not yet created.</p>"; | |
return; | |
} | |
var msgBoard = []; | |
// Ready is default. | |
var transaction = idb_.transaction(idb_.objectStoreNames, IDBTransaction.READ_ONLY); | |
// Get all results. | |
var request = transaction.objectStore("myObjectStore").openCursor(); | |
// | |
// | |
// This callback will continue to be called until we have no more results. | |
request.onsuccess = function(e) { | |
// FF4 requires e.result. IDBRequest.request isn't set | |
// FF5/Chrome works fine. | |
var cursor = request.result || e.result; | |
if (!cursor) { | |
idResultsWrapper_.innerHTML = '<ul class="record-list" id="idb-results">' + msgBoard.join('') + '</ul>'; | |
return; | |
} | |
msgBoard.push('<li><span class="keyval" contenteditable onblur="indexedDbUtil.updateKey(\'', | |
cursor.key, '\', this)">', cursor.key, '</span> ', | |
'=> <span class="keyval" contenteditable onblur="indexedDbUtil.updateValue(\'', | |
cursor.key, '\', this)">', cursor.value, '</span> ', | |
'<a href="javascript:void(0)" onclick="indexedDbUtil.deleteKey(\'', | |
cursor.key, '\')">[Delete]</a></li>'); | |
cursor.continue(); | |
} | |
request.onerror = idbError_; | |
} | |
// Simple example to show all our records in the DB | |
function showAll_() { | |
document.getElementById("ourList").innerHTML = "" ; | |
var request = window.indexedDB.open("Test", | |
"Our Test database"); | |
request.onsuccess = function(event) { | |
// Enumerate the entire object store. | |
// request = event.currentTarget.result.objectStoreNames("myObjectStore").openCursor(); | |
var transaction = idb_.transaction(idb_.objectStoreNames, IDBTransaction.READ_ONLY); // Ready is default. | |
var request = transaction.objectStore("myObjectStore").openCursor(); | |
request.onsuccess = function(event) { | |
var cursor = request.result || event.result; | |
// If cursor is null then we've completed the enumeration. | |
if (!cursor) { | |
return; | |
} | |
var element = document.createElement("div"); | |
element.textContent = "key: " + cursor.key + "=> Value: " + cursor.value; | |
document.getElementById("ourList").appendChild(element); | |
cursor. | |
continue (); | |
}; | |
}; | |
} | |
function idbCreate_() { | |
if (!idb_) { | |
if (idbRequest_) { | |
// If indexedDB is still opening, just queue this up. | |
idbRequest_.addEventListener('success', idb_.removeObjectStore, false); | |
} | |
return; | |
} | |
var request = idb_.setVersion('the new version string'); | |
request.onerror = idbError_; | |
request.onsuccess = function(e) { | |
if (!idb_.objectStoreNames.contains('myObjectStore')) { | |
try { | |
// FF is requiring the 2nd keyPath arg. It can be optional | |
var objectStore = idb_.createObjectStore('myObjectStore', null); | |
idbLog_.innerHTML = "<p>Object store created.</p>"; | |
} catch (err) { | |
idbLog_.innerHTML = '<p class="error">' + err.toString() + '</p>'; | |
} | |
} else { | |
idbLog_.innerHTML = '<p class="error">Object store already exists.</p>'; | |
} | |
} | |
} | |
function idbSet_() { | |
if (!idb_) { | |
if (idbRequest_) { | |
// If indexedDB is still opening, just queue this up. | |
idbRequest_.addEventListener('success', idb_.removeObjectStore, false); | |
} | |
return; | |
} | |
if (!idb_.objectStoreNames.contains('myObjectStore')) { | |
idbLog_.innerHTML = "<p class=\"error\">Object store doesn't exist.</p>"; | |
return; | |
} | |
// Create a transaction that locks the world. | |
var objectStore = idb_.transaction(idb_.objectStoreNames, IDBTransaction.READ_WRITE) | |
.objectStore("myObjectStore"); | |
var request = objectStore.put( | |
document.getElementById('idb-value').value, | |
document.getElementById('idb-key').value); | |
request.onerror = idbError_; | |
request.onsuccess = idbShow_; | |
} | |
function updateKey_(key, element) { | |
var newKey = element.textContent; | |
// Create a transaction that locks the world. | |
var transaction = idb_.transaction(idb_.objectStoreNames, IDBTransaction.READ_WRITE); | |
var objectStore = transaction.objectStore("myObjectStore"); | |
var request = objectStore.get(key); | |
request.onerror = idbError_; | |
request.onsuccess = function(e) { | |
// FF4 requires e.result. IDBRequest.request isn't set. | |
// FF5/Chrome works fine. | |
var value = e.result || this.result; | |
if (objectStore.delete) { | |
var request = objectStore.delete(key); | |
} else { | |
// FF4 not up to spect | |
var request = objectStore.remove(key); | |
} | |
request.onerror = idbError_; | |
request.onsuccess = function(e) { | |
var request = objectStore.add(value, newKey); | |
request.onerror = idbError_; | |
request.onsuccess = idbShow_; | |
}; | |
}; | |
} | |
function updateValue_(key, element) { | |
// Create a transaction that locks the world. | |
var transaction = idb_.transaction(idb_.objectStoreNames, IDBTransaction.READ_WRITE); | |
var objectStore = transaction.objectStore("myObjectStore"); | |
var request = objectStore.put(element.textContent, key); | |
request.onerror = idbError_; | |
request.onsuccess = idbShow_; | |
} | |
function deleteKey_(key) { | |
// Create a transaction that locks the world. | |
var transaction = idb_.transaction(idb_.objectStoreNames, IDBTransaction.READ_WRITE); | |
var objectStore = transaction.objectStore("myObjectStore"); | |
if (objectStore.delete) { | |
var request = objectStore.delete(key); | |
} else { | |
// FF4 not up to spect | |
// FF5 and Chrome - are by the book :) | |
var request = objectStore.remove(key); | |
} | |
request.onerror = idbError_; | |
request.onsuccess = idbShow_; | |
} | |
function idbRemove_() { | |
if (!idb_) { | |
if (idbRequest_) { | |
// If indexedDB is still opening, just queue this up. | |
idbRequest_.addEventListener('success', idb_.removeObjectStore, false); | |
} | |
return; | |
} | |
var request = idb_.setVersion("the new version string"); | |
request.onerror = idbError_; | |
request.onsuccess = function(e) { | |
if (idb_.objectStoreNames.contains('myObjectStore')) { | |
try { | |
// Spec has been updated to deleteObjectStore. | |
if (idb_.deleteObjectStore) { | |
idb_.deleteObjectStore('myObjectStore'); | |
} else { | |
idb_.removeObjectStore('myObjectStore'); | |
} | |
idResultsWrapper_.innerHTML = ''; | |
idbLog_.innerHTML = "<p>Object store removed.</p>"; | |
} catch (err) { | |
idbLog_.innerHTML = '<p class="error">' + err.toString() + '</p>'; | |
} | |
} else { | |
idbLog_.innerHTML = "<p class=\"error\">Object store doesn't exist.</p>"; | |
} | |
}; | |
} | |
return { | |
idbSet: idbSet_, | |
idbCreate: idbCreate_, | |
idbRemove: idbRemove_, | |
updateKey: updateKey_, | |
updateValue: updateValue_, | |
deleteKey: deleteKey_, | |
showAll: showAll_ | |
} | |
})(); | |
</script> | |
</section> | |
<div id='footer'> | |
<h3>Tips</h3> | |
<ul> | |
<li>If you can't even open the DB and you something like this error: | |
<p> | |
The operation failed for reasons unrelated to the database itself and not covered by any other error code." code: "1<br/> | |
[Break On This Error] idbRequest_ = ..., "Our Amazing test object IndexDB"); | |
</p> | |
you need to run your page from a web server and NOT fetch it as local file. | |
</li> | |
</ul> | |
</div> | |
</body> | |
</html> |
Glad you like it :)
May i use this as a base to my html5 CRUD?
Sure.
Good luck.
I've added a fix that it's a must from Chrome 17.
Chrome 17 will now through an error if an indexedDB transaction isn't scoped to an object store.
// so no more lines like this:
var transaction = db.transaction([], IDBTransaction.READ_ONLY);
//Which is passing an empty array to our database.transaction
//You should scope to a particular object store, or list of object stores:
// all stores (equivalent to what use to be marked as empty array. )
var transaction = db.transaction(db.objectStoreNames, IDBTransaction.READ_ONLY);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
very nice