228 lines
5.7 KiB
JavaScript
228 lines
5.7 KiB
JavaScript
|
var Product = Backbone.Model.extend({});
|
||
|
|
||
|
var Item = Backbone.Model.extend({
|
||
|
update: function(amount) {
|
||
|
if (amount === this.get('quantity')) {
|
||
|
return this;
|
||
|
}
|
||
|
this.set({quantity: amount}, {silent: true});
|
||
|
this.collection.trigger('update', this);
|
||
|
return this;
|
||
|
},
|
||
|
|
||
|
price: function() {
|
||
|
return this.get('product').get('price') * this.get('quantity');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
var ProductCollection = Backbone.Collection.extend({
|
||
|
model: Product,
|
||
|
initialize: function(models, options) {
|
||
|
this.url = options.url;
|
||
|
},
|
||
|
|
||
|
comparator: function(item) {
|
||
|
return item.get('title');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
var ItemCollection = Backbone.Collection.extend({
|
||
|
model: Item,
|
||
|
|
||
|
updateItemForProduct: function(product, amount) {
|
||
|
amount = amount != null ? amount : 0;
|
||
|
var pid = product.get('id');
|
||
|
var item = this.detect(function(obj) {
|
||
|
return obj.get('product').get('id') === pid;
|
||
|
});
|
||
|
if (item) {
|
||
|
item.update(amount);
|
||
|
return item;
|
||
|
}
|
||
|
return this.add({
|
||
|
product: product,
|
||
|
quantity: amount
|
||
|
});
|
||
|
},
|
||
|
|
||
|
getTotalCount: function() {
|
||
|
var addup = function(memo, obj) {
|
||
|
return memo + obj.get('quantity');
|
||
|
};
|
||
|
return this.reduce(addup, 0);
|
||
|
},
|
||
|
|
||
|
getTotalCost: function() {
|
||
|
var addup = function(memo, obj) {
|
||
|
return memo + obj.price();
|
||
|
};
|
||
|
return this.reduce(addup, 0);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
var BaseView = Backbone.View.extend({
|
||
|
parent: $('#main'),
|
||
|
className: 'viewport',
|
||
|
|
||
|
initialize: function(options) {
|
||
|
Backbone.View.prototype.initialize.apply(this, arguments);
|
||
|
this.$el.hide();
|
||
|
this.parent.append(this.el);
|
||
|
},
|
||
|
|
||
|
hide: function() {
|
||
|
var dfd = $.Deferred();
|
||
|
if (!this.$el.is(':visible')) {
|
||
|
return dfd.resolve();
|
||
|
}
|
||
|
this.$el.fadeOut('fast', function() {
|
||
|
return dfd.resolve();
|
||
|
});
|
||
|
return dfd.promise();
|
||
|
},
|
||
|
|
||
|
show: function() {
|
||
|
var dfd = $.Deferred();
|
||
|
if (this.$el.is(':visible')) {
|
||
|
return dfd.resolve();
|
||
|
}
|
||
|
this.$el.fadeIn('fast', function() {
|
||
|
return dfd.resolve();
|
||
|
});
|
||
|
return dfd.promise();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
var ProductListView = BaseView.extend({
|
||
|
id: 'productlistview',
|
||
|
template: _.template($("#store_index_template").html()),
|
||
|
|
||
|
initialize: function(options) {
|
||
|
BaseView.prototype.initialize.apply(this, arguments);
|
||
|
this.collection.bind('reset', this.render.bind(this));
|
||
|
},
|
||
|
|
||
|
render: function() {
|
||
|
this.$el.html(this.template({
|
||
|
'products': this.collection.toJSON()
|
||
|
}));
|
||
|
return this;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
var ProductView = BaseView.extend({
|
||
|
className: 'productitemview',
|
||
|
template: _.template($("#store_item_template").html()),
|
||
|
|
||
|
initialize: function(options) {
|
||
|
BaseView.prototype.initialize.apply(this, [options]);
|
||
|
this.itemcollection = options.itemcollection;
|
||
|
},
|
||
|
|
||
|
events: {
|
||
|
"keypress .uqf" : "updateOnEnter",
|
||
|
"click .uq" : "update"
|
||
|
},
|
||
|
|
||
|
update: function(e) {
|
||
|
e.preventDefault();
|
||
|
return this.itemcollection.updateItemForProduct(this.model, parseInt(this.$('.uqf').val()));
|
||
|
},
|
||
|
|
||
|
updateOnEnter: function(e) {
|
||
|
if (e.keyCode === 13) {
|
||
|
this.update(e);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
render: function() {
|
||
|
this.$el.html(this.template(this.model.toJSON()));
|
||
|
return this;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
var CartWidget = Backbone.View.extend({
|
||
|
el: $('.cart-info'),
|
||
|
template: _.template($('#store_cart_template').html()),
|
||
|
|
||
|
initialize: function() {
|
||
|
Backbone.View.prototype.initialize.apply(this, arguments);
|
||
|
this.collection.bind('update', this.render.bind(this));
|
||
|
},
|
||
|
|
||
|
render: function() {
|
||
|
var tel = this.$el.html(this.template({
|
||
|
'count': this.collection.getTotalCount(),
|
||
|
'cost': this.collection.getTotalCost()
|
||
|
}));
|
||
|
tel.animate({ paddingTop: '30px' }).animate({ paddingTop: '10px' });
|
||
|
return this;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
var BackboneStore = Backbone.Router.extend({
|
||
|
views: {},
|
||
|
products: null,
|
||
|
cart: null,
|
||
|
|
||
|
routes: {
|
||
|
"": "index",
|
||
|
"item/:id": "product"
|
||
|
},
|
||
|
|
||
|
initialize: function(data) {
|
||
|
Backbone.Router.prototype.initialize.apply(this, arguments);
|
||
|
this.cart = new ItemCollection();
|
||
|
new CartWidget({ collection: this.cart });
|
||
|
this.products = new ProductCollection([], { url: 'data/items.json' });
|
||
|
this.views = {
|
||
|
'_index': new ProductListView({ collection: this.products })
|
||
|
};
|
||
|
$.when(this.products.fetch({ reset: true })).then(function() {
|
||
|
return window.location.hash = '';
|
||
|
});
|
||
|
},
|
||
|
|
||
|
hideAllViews: function() {
|
||
|
return _.filter(_.map(this.views, function(v) { return v.hide(); }),
|
||
|
function(t) { return t !== null; });
|
||
|
},
|
||
|
|
||
|
index: function() {
|
||
|
var view = this.views['_index'];
|
||
|
return $.when.apply($, this.hideAllViews()).then(function() {
|
||
|
return view.show();
|
||
|
});
|
||
|
},
|
||
|
|
||
|
product: function(id) {
|
||
|
var view = this.views[id];
|
||
|
if (!view) {
|
||
|
var product = this.products.detect(function(p) {
|
||
|
return p.get('id') === id;
|
||
|
});
|
||
|
view = this.views[id] = new ProductView({
|
||
|
model: product,
|
||
|
itemcollection: this.cart
|
||
|
}).render();
|
||
|
}
|
||
|
return $.when(this.hideAllViews()).then(function() {
|
||
|
return view.show();
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
$(document).ready(function() {
|
||
|
new BackboneStore();
|
||
|
return Backbone.history.start();
|
||
|
});
|
||
|
|