This explains how to load sorted and filtered data on a responsive way thanks to indexeddb
A Pen by Juan Cortines on CodePen.
<div id="example"> | |
<div class="box" data-bind="visible: preparingData"> | |
Preparing data... | |
</div> | |
<div class="box"> | |
<div> | |
<span>Text filter:</span> | |
<input type="text" data-bind="value: textFilter, valueUpdate: 'input', disable: preparingData"> | |
</div> | |
<div> | |
<span>Sort by:</span> | |
<select data-bind="value: sortCriteria, options: sortCriteriaOptions, disable: preparingData"></select> | |
</div> | |
</div> | |
<div class="box"> | |
<span>Movies (<!-- ko text: movies().length --><!-- /ko -->):</span> | |
<div data-bind="foreach: movies"> | |
<div class="box"> | |
<div> | |
<span>Title:</span> | |
<!-- ko text: name --><!-- /ko --> | |
</div> | |
<div> | |
<span>Year:</span> | |
<!-- ko text: year --><!-- /ko --> | |
</div> | |
</div> | |
</div> | |
<div data-bind="visible: loadingData"> | |
Loading... | |
</div> | |
</div> | |
</div> |
This explains how to load sorted and filtered data on a responsive way thanks to indexeddb
A Pen by Juan Cortines on CodePen.
var database = { | |
id: 'example', | |
description: 'example', | |
migrations: [ | |
{ | |
version: '1.0', | |
migrate: function (transaction, next) { | |
var movies = transaction.db.createObjectStore('movies', {keyPath: 'id'}); | |
movies.createIndex('name', 'name', { | |
unique: true | |
}); | |
movies.createIndex('year', 'year', { | |
unique: false | |
}); | |
next(); | |
} | |
} | |
] | |
}; | |
var Movie = Backbone.Model.extend({ | |
storeName: 'movies', | |
database: database, | |
defaults: { | |
name: '', | |
year: undefined | |
} | |
}); | |
var Movies = Backbone.Collection.extend({ | |
storeName: 'movies', | |
database: database, | |
model: Movie | |
}); | |
var getRandomString = function () { | |
var i, | |
text = '', | |
possible = 'AB CDEFGH IJKLMNOPQ RSTUVWXY Zabcdefgh ijklmnopq rstuvwxyz 123'; | |
for (i = 0; i < 10; i++) { | |
text += possible.charAt(Math.floor(Math.random() * possible.length)); | |
} | |
return text; | |
}; | |
var getRandomDate = function () { | |
return Math.round(Math.random() * Date.now()); | |
}; | |
var prepareData = function (oncomplete) { | |
var movies = new Movies(); | |
movies.once('sync', function () { | |
var count, | |
request = indexedDB.open('example', '1.0'); | |
request.onsuccess = function () { | |
var db = request.result, | |
transaction = db.transaction(['movies'], 'readwrite'), | |
store = transaction.objectStore('movies'); | |
transaction.oncomplete = function (event) { | |
oncomplete(); | |
}; | |
for (count = 1; count < 100000; count++) { | |
store.put({ | |
id: count, | |
name: getRandomString(), | |
year: getRandomDate() | |
}); | |
} | |
}; | |
}); | |
movies.create({ | |
id: 0, | |
name: getRandomString(), | |
year: getRandomDate() | |
}); | |
}; | |
var ViewModel = function () { | |
var promise, | |
movies = new Movies(), | |
loadMoviesCollection = function (textFilter, sortCriteria) { | |
if (promise) { | |
promise.abort(); | |
} | |
movies.reset(); | |
this.loadingData(true); | |
promise = movies.fetch({ | |
indexName: sortCriteria, | |
addIndividually: true, | |
filter: function (movie) { | |
return movie.name.indexOf(textFilter) !== -1; | |
} | |
}).done(function () { | |
this.loadingData(false); | |
}.bind(this)); | |
}.bind(this); | |
this.movies = kb.collectionObservable(movies, { | |
view_model: function (movie) { | |
this.name = movie.get('name'); | |
this.year = new Date(movie.get('year')).getFullYear(); | |
}, | |
auto_compact: true | |
}); | |
this.preparingData = ko.observable(true); | |
this.loadingData = ko.observable(false); | |
this.textFilter = ko.observable(''); | |
this.sortCriteria = ko.observable(); | |
this.sortCriteriaOptions = ko.observableArray(['name', 'year']); | |
this.textFilter.subscribe(function (text) { | |
loadMoviesCollection(text, this.sortCriteria()); | |
}.bind(this)); | |
this.sortCriteria.subscribe(function (criteria) { | |
loadMoviesCollection(this.textFilter(), criteria); | |
}.bind(this)); | |
}; | |
var viewModel = new ViewModel(); | |
ko.applyBindings(viewModel, $('#example')[0]); | |
prepareData(function () { | |
viewModel.preparingData(false); | |
}); |
.box { | |
border-style: solid; | |
border-width: 1px; | |
} |