A Javascript class object that acts like Rails' ActiveRecord with localStorage.
///////////////////////////////////////////////////////////////////////////////
//
// Simulate an activerecord-like model class
// in general JavaScript is a class-less language. Everything is an object.
// http://www.phpied.com/3-ways-to-define-a-javascript-class/
//
///////////////////////////////////////////////////////////////////////////////
// ## Data
// Objects should be indexed by id
// {"149":{"patient_related":false,"lock_version":0,"uuid":"918497e0-29a4-012f-1aca-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":108,"job_type_id":269,"description":"Light burned out","created_at":"2012-01-25T11:04:29-06:00","id":149},"150":{"patient_related":true,"lock_version":0,"uuid":"9194e050-29a4-012f-1acb-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":109,"job_type_id":272,"description":"Toilet stopped up","created_at":"2012-01-25T11:04:29-06:00","id":150},"151":{"patient_related":true,"lock_version":0,"uuid":"919607f0-29a4-012f-1acc-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":109,"job_type_id":272,"description":"Drain clogged","created_at":"2012-01-25T11:04:29-06:00","id":151},"152":{"patient_related":true,"lock_version":0,"uuid":"91970ba0-29a4-012f-1acd-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":108,"job_type_id":267,"description":"Room too cold","created_at":"2012-01-25T11:04:29-06:00","id":152},"153":{"patient_related":true,"lock_version":0,"uuid":"919801c0-29a4-012f-1ace-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":108,"job_type_id":267,"description":"Room too hot","created_at":"2012-01-25T11:04:29-06:00","id":153},"154":{"patient_related":false,"lock_version":0,"uuid":"9198f860-29a4-012f-1acf-005056af31ef","updated_at":"2013-01-03T21:04:05-06:00","facility_id":13,"priority_id":109,"job_type_id":283,"description":"Door won't close","created_at":"2012-01-25T11:04:29-06:00","id":154},"155":{"patient_related":false,"lock_version":0,"uuid":"9199e740-29a4-012f-1ad0-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":108,"job_type_id":269,"description":"Power out","created_at":"2012-01-25T11:04:29-06:00","id":155},"156":{"patient_related":true,"lock_version":0,"uuid":"919ad520-29a4-012f-1ad1-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":108,"job_type_id":283,"description":"TV is broken","created_at":"2012-01-25T11:04:29-06:00","id":156},"157":{"patient_related":true,"lock_version":0,"uuid":"919bc420-29a4-012f-1ad2-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":108,"job_type_id":272,"description":"No hot water","created_at":"2012-01-25T11:04:29-06:00","id":157},"158":{"patient_related":true,"lock_version":0,"uuid":"919cb3f0-29a4-012f-1ad3-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":108,"job_type_id":283,"description":"TV remote does not work","created_at":"2012-01-25T11:04:29-06:00","id":158},"159":{"patient_related":false,"lock_version":0,"uuid":"919da3f0-29a4-012f-1ad4-005056af31ef","updated_at":"2012-01-25T11:04:29-06:00","facility_id":13,"priority_id":109,"job_type_id":272,"description":"Water leak","created_at":"2012-01-25T11:04:29-06:00","id":159},"652":{"patient_related":false,"lock_version":0,"uuid":"da2dede0-3839-0130-1c8c-065142d3bcb8","updated_at":"2013-01-03T19:13:36-06:00","facility_id":13,"priority_id":108,"job_type_id":283,"description":"Empty cardboard bailer","created_at":"2013-01-03T19:13:20-06:00","id":652},"653":{"patient_related":true,"lock_version":0,"uuid":"ffe96d10-3839-0130-1c90-065142d3bcb8","updated_at":"2013-01-03T19:14:23-06:00","facility_id":13,"priority_id":108,"job_type_id":267,"description":"Ice machine not working","created_at":"2013-01-03T19:14:23-06:00","id":653},"654":{"patient_related":false,"lock_version":0,"uuid":"2f7b3830-383a-0130-1c99-065142d3bcb8","updated_at":"2013-01-03T19:15:43-06:00","facility_id":13,"priority_id":107,"job_type_id":267,"description":"Defrost refridgerator","created_at":"2013-01-03T19:15:43-06:00","id":654},"655":{"patient_related":false,"lock_version":0,"uuid":"8fb19ba0-383a-0130-1ca0-065142d3bcb8","updated_at":"2013-01-03T19:18:25-06:00","facility_id":13,"priority_id":107,"job_type_id":283,"description":"Cabinet broken","created_at":"2013-01-03T19:18:25-06:00","id":655},"656":{"patient_related":false,"lock_version":0,"uuid":"dfd7c390-3848-0130-6525-065142f28507","updated_at":"2013-01-03T21:01:05-06:00","facility_id":13,"priority_id":107,"job_type_id":283,"description":"Remove bed","created_at":"2013-01-03T21:00:52-06:00","id":656},"657":{"patient_related":true,"lock_version":0,"uuid":"f5de0a10-3848-0130-652b-065142f28507","updated_at":"2013-01-03T21:01:36-06:00","facility_id":13,"priority_id":109,"job_type_id":283,"description":"Need bed","created_at":"2013-01-03T21:01:29-06:00","id":657},"658":{"patient_related":true,"lock_version":0,"uuid":"2923eae0-3849-0130-6531-065142f28507","updated_at":"2013-01-03T21:02:55-06:00","facility_id":13,"priority_id":109,"job_type_id":272,"description":"Toilet overflowing","created_at":"2013-01-03T21:02:55-06:00","id":658},"659":{"patient_related":false,"lock_version":0,"uuid":"e3e490e0-3851-0130-6653-065142f28507","updated_at":"2013-01-03T22:05:24-06:00","facility_id":13,"priority_id":109,"job_type_id":283,"description":"Noise","created_at":"2013-01-03T22:05:24-06:00","id":659}}
// ## Use
// var Workorder = new Model('workorders');
// ### Where
// var date = new Date();
// Workorder.where({name:"MichaelMinter",age:28,created_at:date,admin:true},{created_at:'<'})
function Model(table){
"use strict";
if (this.constructor == Model) {
var _table = localStorage.getObject(table);
if (_table == null) {
localStorage.setObject(table, {});
}
}
this.all = function(){
return localStorage.getObject(table);
}
this.find = function(id){
return localStorage.getObject(table)[id];
}
this.first = function(){
var _table = localStorage.getObject(table);
for (var o in _table)
{
return _table[o];
}
}
this.last = function(){
var _table = localStorage.getObject(table);
var _return = "";
for (var o in _table)
{
_return = _table[o];
}
return _return;
}
this.where = function(obj,options){
var _table = localStorage.getObject(table);
var returnData = {};
for (var t in _table)
{
var checkSum = [];
var checkCount = 0;
for (var o in obj)
{
switch(typeof obj[o])
{
case 'string':
// string actually utilizes regex (case insensitive)
if (_table[t][o] != null && eval('_table[t][o].search(/' + obj[o] + '/i)') > -1)
{
checkSum.push(true);
}
break;
case 'number':
if (_table[t][o] != null && _table[t][o] == obj[o])
{
checkSum.push(true);
}
break;
case 'object':
// object (date) requires option
var dateLookup = new Date(_table[t][o]).getTime();
var dateNow = new Date().getTime();
// TODO: replace with eval
switch (options[o])
{
case '>':
if (dateLookup > dateNow)
{
checkSum.push(true);
}
break;
case '<':
if (dateLookup < dateNow)
{
checkSum.push(true);
}
break;
case '>=':
if (dateLookup >= dateNow)
{
checkSum.push(true);
}
break;
case '<=':
if (dateLookup <= dateNow)
{
checkSum.push(true);
}
break;
default:
if (dateLookup == dateNow)
{
checkSum.push(true);
}
}
break;
case 'boolean':
break;
case 'null':
if (_table[t][o] == null)
{
checkSum.push(true);
}
break;
default:
}
checkCount++;
}
if (checkSum.length == checkCount && checkSum.indexOf(true) >= 0 && checkSum.indexOf(false) == -1)
{
returnData[t] = _table[t];
}
}
return returnData;
}
this.create = function(obj){
var _table = localStorage.getObject(table);
_table[obj.id] = obj;
localStorage.setObject(table, _table);
}
this.update = function(obj){
var _table = localStorage.getObject(table);
_table[obj.id] = obj;
localStorage.setObject(table, _table);
}
this.destroy = function(id){
var _table = localStorage.getObject(table);
delete _table[id];
localStorage.setObject(table, _table);
}
this.destroy_all = function(){
localStorage.setItem(table, '{}');
}
}
if (window.Storage){
Storage.prototype.setObject = function(key, value) {
"use strict";
this.setItem(key, JSON.stringify(value));
};
Storage.prototype.getObject = function(key) {
"use strict";
var value = this.getItem(key);
return value && JSON.parse(value);
};
} else {
alert('localStorage is not supported on this browser')
}