Skip to content

Instantly share code, notes, and snippets.

@joshbedo
Last active August 29, 2015 13:55
Show Gist options
  • Save joshbedo/8789244 to your computer and use it in GitHub Desktop.
Save joshbedo/8789244 to your computer and use it in GitHub Desktop.
//include lo-dash for averaging hover times and loops
//include benchmark.js for testing function runtimes
//make tags more versatile and use indexOf to see if the tag exists
console.time("executeTime");
var StoreStats = (function($, window, document) {
"use strict";
var scope = document.querySelectorAll(".storeStats"),$scope = $(scope),
socket = io.connect("http://ec2-54-184-116-0.us-west-2.compute.amazonaws.com:3000/"),
$Cart;
var Product = {
clickEvent: function(obj) {
return function() {
StoreStats.checkout.addItem( obj, function(res) {
//makes sure items is added before submitting purchase
if(res) {
//socket.emit("item added to cart!", "clicked on " + obj.title );
}
});
};
},
removeEvent: function(item) {
return function() {
StoreStats.checkout.remove( item, function(res) {
//socket emit removed
console.log("removed item:", item);
});
};
},
checkoutEvent: function() {
return function() {
StoreStats.checkout.buy(function(res) {
if(res) {
socket.emit("purchase", res);
}
});
};
},
hoverEvent: function() {
}
};
function Store() {
var defaults = {
tags:["name","tag","img"],
currency: "USD",
language: "english-us",
itemClass: ".item",
cartColumns: ["title","price","image","desc"]
};
this.init = function(opts) {
this.settings = $.extend(defaults, opts);
//get products by cartColumns
var products = this.getProducts(this.settings.cartColumns);
attachEvents(products);
};
this.getProducts = function(cartColumns) {
//loop through cartColumns and check for class else check for tag
//once tag is found create new object attaching content and name
//append to newArr and return
var newArr = [], i, $items = $scope.find(".store .s-item");
$items.each(function(i){
//loop through each item on the page and then generate an object with each of the cartColumns
//and get the content
var obj = {}, n, $this = $(this), currentCol;
for(n = 0;n < cartColumns.length;++n) {
currentCol = cartColumns[n];
if(currentCol.hasOwnProperty("tag") && currentCol.hasOwnProperty("name")) {
obj[currentCol.name] = (currentCol.tag === "img") ?
$this.find(currentCol.tag).attr("src") : $this.find(currentCol.tag).text();
obj.el = $this;
}
}
newArr.push(obj);
});
return newArr;
};
function attachEvents(products) {
//attaches events to products on page
var o, $this;
for(o = 0;o < products.length;++o) {
$this = products[o].el;
//attach events
$this.find("button").on("click", Product.clickEvent(products[o]) );
$this.on("hover", Product.hoverEvent(o) );
//causes JSON circular type error when saving, plus we don't really need the reference anymore
//after attaching the events
delete products[o].el;
}
}
}
Store.prototype.checkout = new Checkout();
function Checkout() {
var checkout = {
items: [],
localStorage: window.localStorage,
engageTimes: [],
paymentType: {
type:"PayPal",
email:"joshbedo@yahoo.com"
}
};
function calculateTotal(items) {
var total = 0, i, item_length = items.length, item;
if(items !== undefined) {
for(i = 0;i < item_length;++i) {
item = items[i];
total += parseFloat(item.price.slice(1, item.price.length));
}
}
return total;
}
//attach single event to each item as it's added
//better than reattaching all events every update
function attachEvent(item) {
}
this.getItems = function(parse) {
var items = checkout.localStorage.getItem("ss_items");
if(parse === true && items !== null ) {
items = JSON.parse(items);
}
return (items) ? items : [];
};
this.addItem = function(item, cb) {
var items = this.getItems(true);
items.push(item);
checkout.localStorage.setItem("ss_items", JSON.stringify(items) );
this.update(item);
cb = (typeof cb === "function") ? cb(items) : undefined;
return "item added!";
};
this.init = function() {
//need to implement template var container = _.template(template, data); $('body').append(container);
var items = this.getItems();
$Cart = $("<ul />", {
"id": "ss_checkout",
"class": "ss_checkout"
});
$("body").append($Cart).append("<span id='total'></span> <a href='javascript:;' id='checkout'>Checkout</a>");
$("#checkout").on("click", Product.checkoutEvent() );
if(items) {
this.update();
}
};
this.remove = function(item) {
//var items = (this.getItems()) ? JSON.parse(this.getItems()) : undefined;
//can now pass true as parse argument
var items = this.getItems(true);
if(items) {
}
};
this.update = function(item) {
//refactor to add new item and not read all items
var items = this.getItems(true),
total = calculateTotal( items ),
i;
if(item) {
items.push(item);
$Cart.append("<li>" + item.title + " Price: " + item.price + " <a href='#remove' class='remove'>x</a></li>");
}
if(item === undefined && items) {
$Cart.empty();
for(i = 0;i < items.length;++i) {
//turn into template
var $li = $("<li>" + items[i].title + " Price: " + items[i].price + " <a href='#remove' class='remove'>x</a></li>");
$Cart.append($li);
}
}
$("body").find("#total").text("Total: " + total);
};
this.buy = function(cb) {
var items = this.getItems(true);
console.log(items);
if(items.length > 0 && items instanceof Array){
//more paypal api integration goes here
items = {
products: items,
total: calculateTotal( items ),
apiKey: StoreStats.settings.apiKey
};
cb = (typeof cb === "function") ? cb(items) : undefined;
}
};
this.init();
}
return new Store();
}($, window, document));
StoreStats.init({
apiKey: "5bb628b36b35f80984239f3a0bc62f49",
paymentType: {
type: "Paypal",
api: "code here"
},
tax: 0.075,
cartColumns: [
{tag: "h1", name: "title"},
{tag: "p", name: "description" },
{tag: "img", name: "image"},
{tag: "span", name: "price"}
]
});
console.timeEnd('executeTime');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment