<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Offline-First Site</title>
</head>
<body>
<h1>My Offline-First App</h1>
<div id="app"></div>
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="node_modules/underscore/underscore-min.js"></script>
<script src="node_modules/backbone/backbone-min.js"></script>
<script src="node_modules/localforage/dist/localforage.min.js"></script>
<script src="app.js"></script>
</body>
</html>
// Define a Backbone Model
var Item = Backbone.Model.extend({
defaults: {
name: ''
}
});
// Define a Backbone Collection
var ItemCollection = Backbone.Collection.extend({
model: Item,
// Save data to localForage
saveToLocalForage: function() {
localforage.setItem('items', this.toJSON());
},
// Load data from localForage
loadFromLocalForage: function() {
var self = this;
localforage.getItem('items').then(function(data) {
if (data) {
self.reset(data);
}
});
}
});
// Define a Backbone View
var ItemView = Backbone.View.extend({
tagName: 'li',
template: _.template('<%= name %>'),
initialize: function() {
this.listenTo(this.model, 'change', this.render);
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
var AppView = Backbone.View.extend({
el: '#app',
initialize: function() {
this.collection = new ItemCollection();
this.collection.loadFromLocalForage();
this.render();
// Save to localForage when collection changes
this.listenTo(this.collection, 'add remove reset', this.collection.saveToLocalForage);
},
events: {
'keypress #new-item': 'createItemOnEnter'
},
render: function() {
var input = $('<input>', { id: 'new-item', placeholder: 'Enter item name' });
var list = $('<ul>');
this.$el.append(input, list);
this.collection.each(this.addItem, this);
return this;
},
createItemOnEnter: function(e) {
if (e.which === 13) { // Enter key pressed
var name = $('#new-item').val().trim();
if (name) {
this.collection.add(new Item({ name: name }));
$('#new-item').val('');
}
}
},
addItem: function(item) {
var view = new ItemView({ model: item });
this.$('ul').append(view.render().el);
}
});
// Initialize the application
new AppView();