IndexedDB and Date Example
Join the DZone community and get the full member experience.
Join For Freeabout an hour ago i gave a presentation on indexeddb. one of the attendees asked about dates and being able to filter based on a date range. i told him that my assumption was that you would need to convert the dates into numbers and use a number-based range. turns out i was wrong. here is an example.
i began by creating an objectstore that used an index on the created field. since our intent is to search via a date field, i decided "created" would be a good name. i also named my objectstore as "data". boring, but it works.
var openrequest = indexeddb.open("idbpreso_date1",1);
openrequest.onupgradeneeded = function(e) {
var thisdb = e.target.result;
if(!thisdb.objectstorenames.contains("data")) {
var os = thisdb.createobjectstore("data", {autoincrement:true});
os.createindex("created", "created", {unique:false});
}
}
next - i built a simple way to seed data. i based on a button click event to add 10 objects. each object will have one property, created, and the date object will be based on a random date from now till 7 days in the future.
function doseed() {
var now = new date();
for(var i=0; i<10; i++) {
var daydiff = getrandomint(1, 7);
var thisdate = new date();
thisdate.setdate(now.getdate() + daydiff);
db.transaction(["data"],"readwrite").objectstore("data").add({created:thisdate});
}
}
//credit: mozilla developer center
function getrandomint (min, max) {
return math.floor(math.random() * (max - min + 1)) + min;
}
note that since indexeddb calls are asynchronous, my code should handle updating the user to let them know when the operation is done. since this is just a quick demo though, and since that add operation will complete incredibly fast, i decided to not worry about it.
so at this point we'd have an application that lets us add data containing a created property with a valid javascript date. note i didn't change it to milliseconds. i just passed it in as is.
for the final portion i added two date fields on my page. in chrome this is rendered nicely:
based on these, i can then create an indexeddb range of either bounds, lowerbounds, or upperbounds. i.e., give me crap either after a date, before a date, or inside a date range.
function dosearch() {
var fromdate = document.queryselector("#fromdate").value;
var todate = document.queryselector("#todate").value;
var range;
if(fromdate == "" && todate == "") return;
var transaction = db.transaction(["data"],"readonly");
var store = transaction.objectstore("data");
var index = store.index("created");
if(fromdate != "") fromdate = new date(fromdate);
if(todate != "") todate = new date(todate);
if(fromdate != "" && todate != "") {
range = idbkeyrange.bound(fromdate, todate);
} else if(fromdate == "") {
range = idbkeyrange.upperbound(todate);
} else {
range = idbkeyrange.lowerbound(fromdate);
}
var s = "";
index.opencursor(range).onsuccess = function(e) {
var cursor = e.target.result;
if(cursor) {
s += "<h2>key "+cursor.key+"</h2><p>";
for(var field in cursor.value) {
s+= field+"="+cursor.value[field]+"<br/>";
}
s+="</p>";
cursor.continue();
}
document.queryselector("#status").innerhtml = s;
}
}
the only conversion required here was to take the user input and turn it into "real" date objects. once done, everything works great:
you can run the full demo below.
Published at DZone with permission of Raymond Camden. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments