Skip to content

Instantly share code, notes, and snippets.

@ifandelse
Created January 16, 2012 03:59
Show Gist options
  • Save ifandelse/1618986 to your computer and use it in GitHub Desktop.
Save ifandelse/1618986 to your computer and use it in GitHub Desktop.
Client-side Messaging in JavaScript - Part 2 (Postal.js) Example 2
var cartModule = (function(postal, $){
var cartId = 0,
cartTemplate = "#cart-tmpl",
cartItemTemplate = "#cart-item-tmpl",
cartChildrenSelector = "#cart-list",
wireUpCart = function(cart) {
postal.subscribe("cart", "init", _.bind(cart.init,cart));
postal.subscribe("cart", "item.add", function(item) {
var member = cart.id + "-" + item.id;
if(cart.items[member]) {
cart.items[member].qty++;
cart.items[member].notifyOfChange();
}
else {
cart.items[member] = new CartItem(_.extend(item, { qty: 1, cartId: cart.id }), new CartItemProxy(cartChildrenSelector));
}
});
},
CartPrototype = {
init: function() {
this.items = {};
this.proxy.render(this);
}
},
Cart = function(domProxy) {
var self = this;
self.items = {};
self.id = cartId;
self.proxy = domProxy;
wireUpCart(this);
},
CartDomProxyPrototype = {
render: function(model) {
$(this.selector).html(_.template($(cartTemplate).html(), model));
}
},
CartDomProxy = function(selector) {
this.selector = selector;
},
CartItemPrototype = {
notifyOfChange: function() {
this.proxy.render(this);
}
},
CartItem = function(item, domProxy) {
this.cartId = item.cartId;
this.description = item.description;
this.price = item.price;
this.productId = item.id;
this.proxy = domProxy;
this.qty = item.qty;
this.notifyOfChange();
},
CartItemProxyPrototype = {
render: function(model) {
var item = $("#" + model.cartId + "-" + model.productId);
if(item.length === 0) {
$(this.selector).append(_.template($(cartItemTemplate).html(), model));
}
else {
item.replaceWith(_.template($(cartItemTemplate).html(), model));
}
}
},
CartItemProxy = function(selector) {
this.selector = selector;
};
Cart.prototype = CartPrototype;
CartItem.prototype = CartItemPrototype;
CartItemProxy.prototype = CartItemProxyPrototype;
CartDomProxy.prototype = CartDomProxyPrototype;
return {
start: function(selector) {
return new Cart(new CartDomProxy(selector));
}
}
})(postal, jQuery);
// ProductList Module
var productListModule = (function(postal, $) {
var prodListTemplate = "#product-list-tmpl",
prodItemSelector = "#products li",
wireProductList = function(prodList) {
postal.subscribe("productlist", "init", _.bind(prodList.init, prodList));
postal.subscribe("productlist", "populate", function(data) {
_.each(data.items, function(item) {
prodList.items.push(new Product(item.id, item.description, item.price));
});
prodList.proxy.render(prodList);
});
},
ProductListPrototype = {
init: function() {
this.items = [];
postal.publish("productlist", "request.getproductlist", {});
}
},
ProductList = function(domProxy) {
this.items = [];
this.proxy = domProxy;
wireProductList(this);
},
ProductPrototype = {
onSelect: function() {
postal.publish("productlist", "item.selected", this);
}
},
Product = function(id, desc, price) {
this.id = id;
this.description = desc;
this.price = price;
},
ProductListDomProxyPrototype = {
render: function(model) {
var domSel = $(this.selector);
domSel.html(_.template($(prodListTemplate).html(), model));
_.each(model.items, function(item) {
$("#" + item.id).click(_.bind(item.onSelect, item));
});
$(prodItemSelector)
.append("<span class='tool-tip'>click to add<span>")
.hover( function( e ) {
$( this ).children( ".tool-tip" ).toggle( e.type === "mouseenter" );
});
}
},
ProductListDomProxy = function(selector) {
this.selector = selector;
};
ProductList.prototype = ProductListPrototype;
Product.prototype = ProductPrototype;
ProductListDomProxy.prototype = ProductListDomProxyPrototype;
return {
start: function(selector) {
return new ProductList(new ProductListDomProxy(selector));
}
}
})(postal, jQuery);
// END ProductList Module
// Repository Module
var repositoryModule = (function(postal, amplify) {
var prodListResponse = {
items: [
{ description: "Product 1", id:"prod1", price: 30.00 },
{ description: "Product 2", id:"prod2", price: 11.00 },
{ description: "Product 3", id:"prod3", price: 19.00 },
{ description: "Product 4", id:"prod4", price: 23.00 }
]
};
amplify.request.define("get.productlist", function(settings){
settings.success(prodListResponse);
});
postal.subscribe("repository", "get.productlist", function() {
amplify.request("get.productlist", function(response) {
postal.publish("repository", "response.productlist", response);
});
});
})(postal, amplify);
var summaryModule = (function(postal, $) {
var summaryTemplate = "#summary-tmpl",
summaryItemTemplate = "#summary-item-tmpl",
qtySummarySelector = "#summary-list",
orderTotalSummarySelector = "#summary-list",
wireUpSummary = function(summary) {
postal.subscribe("summary", "init", _.bind(summary.init, summary));
},
wireUpQuantitySummary = function(qtySummary) {
postal.subscribe("summary", "qtychange", function(msg) {
qtySummary.qty++;
qtySummary.notifyOfChange();
});
postal.subscribe("summary", "init", function() {
qtySummary.qty = 0;
qtySummary.notifyOfChange();
});
},
wireUpOrderTotalSummary = function(ordTtlSummary) {
postal.subscribe("summary", "ordertotalchange", function(msg) {
ordTtlSummary.total += msg.price;
ordTtlSummary.notifyOfChange();
});
postal.subscribe("summary", "init", function() {
ordTtlSummary.total = 0;
ordTtlSummary.notifyOfChange();
});
},
SummaryPrototype = {
init: function() {
this.items = [
new QuantitySummary(new SummaryItemDomProxy(qtySummarySelector), "summary-qty"),
new OrderTotalSummary(new SummaryItemDomProxy(orderTotalSummarySelector), "summary-total")
];
this.proxy.render(this);
}
},
Summary = function(domProxy) {
this.items = [];
this.proxy = domProxy;
wireUpSummary(this);
},
SummaryDomProxyPrototype = {
render: function(model) {
$(this.selector).html(_.template($(summaryTemplate).html(), model));
$.each(model.items, function(idx, item){
item.notifyOfChange();
});
}
},
SummaryDomProxy = function(selector) {
this.selector = selector;
},
QuantitySummaryPrototype = {
notifyOfChange: function() {
this.proxy.render({ msg: this.qty + " item(s) selected.", id: this.id });
}
},
QuantitySummary = function(domProxy, id) {
this.qty = 0;
this.id = id;
this.proxy = domProxy;
wireUpQuantitySummary(this);
},
OrderTotalSummaryPrototype = {
notifyOfChange: function() {
this.proxy.render({ msg: "Current Order Total: $" + this.total.toFixed(2), id: this.id });
}
},
OrderTotalSummary = function(domProxy, id) {
this.total = 0;
this.id = id;
this.proxy = domProxy;
wireUpOrderTotalSummary(this);
},
SummaryItemDomProxyPrototype = {
render: function(model) {
var target = $("#" + model.id),
rendered = _.template($(summaryItemTemplate).html(), model);
if(target.length === 0) {
$(this.selector).append(rendered);
}
else {
target.replaceWith(rendered);
}
}
},
SummaryItemDomProxy = function(selector) {
this.selector = selector;
};
Summary.prototype = SummaryPrototype;
SummaryDomProxy.prototype = SummaryDomProxyPrototype;
QuantitySummary.prototype = QuantitySummaryPrototype;
OrderTotalSummary.prototype = OrderTotalSummaryPrototype;
SummaryItemDomProxy.prototype = SummaryItemDomProxyPrototype;
return {
start: function(selector) {
return new Summary(new SummaryDomProxy(selector));
}
}
})(postal, jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment