/*~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ Copyright (c) 2012 Brett Wejrowski wojodesign.com simplecartjs.org http://github.com/wojodesign/simplecart-js VERSION 3.0.5 Dual licensed under the MIT or GPL licenses. ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~*/ /*jslint browser: true, unparam: true, white: true, nomen: true, regexp: true, maxerr: 50, indent: 4 */ function int(value) { return parseInt(value); } // this checks the value and updates it on the control, if needed function checkValue(sender) { let min = sender.min; let max = sender.max; let value = int(sender.value); if (value > max) { sender.value = max; } else if (value < min) { sender.value = min; } } (function (window, document) { /*global HTMLElement */ var typeof_string = typeof "", typeof_undefined = typeof undefined, typeof_function = typeof function () {}, typeof_object = typeof {}, isTypeOf = function (item, type) { return typeof item === type; }, isString = function (item) { return isTypeOf(item, typeof_string); }, isUndefined = function (item) { return isTypeOf(item, typeof_undefined); }, isFunction = function (item) { return isTypeOf(item, typeof_function); }, isObject = function (item) { return isTypeOf(item, typeof_object); }, //Returns true if it is a DOM element isElement = function (o) { return typeof HTMLElement === "object" ? o instanceof HTMLElement : typeof o === "object" && o.nodeType === 1 && typeof o.nodeName === "string"; }, generateSimpleCart = function (space) { // stealing this from selectivizr var selectorEngines = { "MooTools": "$$", "Prototype": "$$", "jQuery": "*" }, // local variables for internal use item_id = 0, item_id_namespace = "SCI-", sc_items = {}, namespace = space || "simpleCart", selectorFunctions = {}, eventFunctions = {}, baseEvents = {}, // local references localStorage = window.localStorage, console = window.console || { msgs: [], log: function (msg) { console.msgs.push(msg); } }, // used in views _VALUE_ = 'value', _TEXT_ = 'text', _HTML_ = 'html', _CLICK_ = 'click', // Currencies currencies = { "USD": { code: "USD", symbol: "$", name: "US Dollar" }, "AUD": { code: "AUD", symbol: "$", name: "Australian Dollar" }, "BRL": { code: "BRL", symbol: "R$", name: "Brazilian Real" }, "CAD": { code: "CAD", symbol: "$", name: "Canadian Dollar" }, "CZK": { code: "CZK", symbol: " Kč", name: "Czech Koruna", after: true }, "DKK": { code: "DKK", symbol: "DKK ", name: "Danish Krone" }, "EUR": { code: "EUR", symbol: "€", name: "Euro" }, "HKD": { code: "HKD", symbol: "$", name: "Hong Kong Dollar" }, "HUF": { code: "HUF", symbol: "Ft", name: "Hungarian Forint" }, "ILS": { code: "ILS", symbol: "₪", name: "Israeli New Sheqel" }, "JPY": { code: "JPY", symbol: "¥", name: "Japanese Yen", accuracy: 0 }, "MXN": { code: "MXN", symbol: "$", name: "Mexican Peso" }, "NOK": { code: "NOK", symbol: "NOK ", name: "Norwegian Krone" }, "NZD": { code: "NZD", symbol: "$", name: "New Zealand Dollar" }, "PLN": { code: "PLN", symbol: "PLN ", name: "Polish Zloty" }, "GBP": { code: "GBP", symbol: "£", name: "Pound Sterling" }, "SGD": { code: "SGD", symbol: "$", name: "Singapore Dollar" }, "SEK": { code: "SEK", symbol: "SEK ", name: "Swedish Krona" }, "CHF": { code: "CHF", symbol: "CHF ", name: "Swiss Franc" }, "THB": { code: "THB", symbol: "฿", name: "Thai Baht" }, "BTC": { code: "BTC", symbol: " BTC", name: "Bitcoin", accuracy: 4, after: true } }, // default options settings = { checkout: { type: "PayPal", email: "you@yours.com" }, currency: "CAD", language: "english-us", cartStyle: "div", cartColumns: [{ attr: "name", label: "Name" }, { attr: "price", label: "Price", view: 'currency' }, { view: "decrement", label: false }, { attr: "quantity", label: "Qty" }, { view: "increment", label: false }, { attr: "total", label: "SubTotal", view: 'currency' }, { view: "remove", text: "Remove", label: false } ], excludeFromCheckout: ['thumb'], shippingFlatRate: 0, shippingServiceName: 'Please Select Shipping', shippingServiceId: 0, shippingCarrier: null, shippingRates: {}, shippingQuantityRate: 0, shippingTotalRate: 0, shippingCustom: null, freeShippingLimit: 0, taxRate: 0, taxShipping: false, data: {}, appliedCredit: 0 }, // main simpleCart object, function call is used for setting options simpleCart = function (options) { // shortcut for simpleCart.ready if (isFunction(options)) { return simpleCart.ready(options); } // set options if (isObject(options)) { return simpleCart.extend(settings, options); } }, // selector engine $engine, // built in cart views for item cells cartColumnViews; // function for extending objects simpleCart.extend = function (target, opts) { var next; if (isUndefined(opts)) { opts = target; target = simpleCart; } for (next in opts) { if (Object.prototype.hasOwnProperty.call(opts, next)) { target[next] = opts[next]; } } return target; }; // create copy function simpleCart.extend({ copy: function (n) { var cp = generateSimpleCart(n); cp.init(); return cp; } }); // add in the core functionality simpleCart.extend({ isReady: false, // this is where the magic happens, the add function add: function (values, opt_quiet) { var info = values || {}, newItem = new simpleCart.Item(info), addItem = true, // optionally supress event triggers quiet = opt_quiet === true ? opt_quiet : false, oldItem; // trigger before add event if (!quiet) { addItem = simpleCart.trigger('beforeAdd', [newItem]); if (addItem === false) { return false; } } //console.log([newItem,info,simpleCart.has(newItem),newItem.id(),newItem.quantity()]); // if the new item already exists, increment the value oldItem = simpleCart.has(newItem); //console.log([oldItem,newItem,values]); if (oldItem) { //console.log([newItem,info,simpleCart.has(newItem),newItem.id(),newItem.quantity()]); oldItem.increment(newItem.quantity()); newItem = oldItem; // otherwise add the item } else { sc_items[newItem.id()] = newItem; } // update the cart simpleCart.update(); if (!quiet) { // trigger after add event simpleCart.trigger('afterAdd', [newItem, isUndefined(oldItem)]); } // return a reference to the added item return newItem; }, // iteration function each: function (array, callback) { var next, x = 0, result, cb, items; if (isFunction(array)) { cb = array; items = sc_items; } else if (isFunction(callback)) { cb = callback; items = array; } else { return; } for (next in items) { if (Object.prototype.hasOwnProperty.call(items, next)) { result = cb.call(simpleCart, items[next], x, next); if (result === false) { return; } x += 1; } } }, find: function (id) { var items = []; // return object for id if it exists if (isObject(sc_items[id])) { return sc_items[id]; } // search through items with the given criteria if (isObject(id)) { simpleCart.each(function (item) { var match = true; simpleCart.each(id, function (val, x, attr) { if (isString(val)) { // less than or equal to if (val.match(/<=.*/)) { val = parseFloat(val.replace('<=', '')); if (!(item.get(attr) && parseFloat(item.get(attr)) <= val)) { match = false; } // less than } else if (val.match(/=/)) { val = parseFloat(val.replace('>=', '')); if (!(item.get(attr) && parseFloat(item.get(attr)) >= val)) { match = false; } // greater than } else if (val.match(/>/)) { val = parseFloat(val.replace('>', '')); if (!(item.get(attr) && parseFloat(item.get(attr)) > val)) { match = false; } // equal to } else if (!(item.get(attr) && item.get(attr) === val)) { match = false; } // equal to non string } else if (!(item.get(attr) && item.get(attr) === val)) { match = false; } return match; }); // add the item if it matches if (match) { items.push(item); } }); return items; } // if no criteria is given we return all items if (isUndefined(id)) { // use a new array so we don't give a reference to the // cart's item array simpleCart.each(function (item) { items.push(item); }); return items; } // return empty array as default return items; }, // return all items items: function () { return this.find(); }, // check to see if item is in the cart already has: function (item) { var match = false; simpleCart.each(function (testItem) { if (testItem.equals(item)) { match = testItem; } }); return match; }, // empty the cart empty: function () { // remove each item individually so we see the remove events var newItems = {}; simpleCart.each(function (item) { // send a param of true to make sure it doesn't // update after every removal // keep the item if the function returns false, // because we know it has been prevented // from being removed if (item.remove(true) === false) { newItems[item.id()] = item } }); sc_items = newItems; settings.shippingFlatRate = 0; settings.shippingServiceName = 'Please Select Shipping'; settings.shippingServiceId = 0, settings.shippingCarrier = null; settings.shippingRates = {}; simpleCart.update(); }, // functions for accessing cart info quantity: function () { var quantity = 0; simpleCart.each(function (item) { quantity += item.quantity(); }); return quantity; }, uniqueQuantity: function () { var quantity = 0; simpleCart.each(function (item) { quantity += 1; }); return quantity; }, total: function () { var total = 0; simpleCart.each(function (item) { total += item.total(); }); return Number(parseFloat(total).toFixed(2)); }, totalForTax: function () { var total = 0; simpleCart.each(function (item) { total += (item.total() * item.get('is_tax_able')); }); return Number(parseFloat(total).toFixed(2)); }, totalTaxs: function () { var total = 0; simpleCart.each(function (item) { total += item.itemTax(); }); //console.log(total); return Number(parseFloat(total).toFixed(2)); }, grandTotal: function () { //console.log(simpleCart.total() , simpleCart.tax() , simpleCart.shipping() , simpleCart.itemsRulesValue()); var res = Number(parseFloat(simpleCart.total() + simpleCart.tax() + simpleCart.shipping() + simpleCart.itemsRulesValue()).toFixed(2)); // console.log([simpleCart.total(), simpleCart.tax(), simpleCart.shipping(), simpleCart.itemsRulesValue(), res]); return res; }, grandTotalBeforeCredit: function () { return Number(parseFloat(simpleCart.total() + simpleCart.tax() + simpleCart.shipping() + simpleCart.itemsRulesValue(false, false, true)).toFixed(2)); }, grandTotalAfterTax: function () { return Number(parseFloat(simpleCart.total() + simpleCart.tax() + simpleCart.shipping()).toFixed(2)); }, grandTotalBeforeTax: function () { //console.log(simpleCart.total(), simpleCart.itemsRulesValue(true, false),simpleCart.shipping()); // var amount = (simpleCart.total() + simpleCart.itemsRulesValue(true, false) + simpleCart.shipping());; var amount = (simpleCart.total() + simpleCart.itemsRulesValue(true, false, true)); amount = Number(parseFloat(amount).toFixed(2)); //console.log( amount); return amount; }, outerGrandTotal: function () { return Number(parseFloat(simpleCart.total() + simpleCart.itemsRulesValue()).toFixed(2)); }, getIds: function () { var ids = []; simpleCart.each(function (item, x) { ids.push(item.id()); }) return ids; }, getItemsInfo: function () { var info = []; var total = simpleCart.total(); simpleCart.each(function (item, x) { info.push({ id: item.id(), quantity: item.quantity(), isDeposit: item.get("is_deposit"), isBackorder: item.get("is_backorder"), enableBackorders: (item.get("item_backorder") != undefined ? item.get("item_backorder") : settings.enableBackorders), shippable: (item.get("shippable") >= 0 ? item.get("shippable") : -1), isMicrofiche: (item.get("is_microfiche") != undefined ? item.get("is_microfiche") : 0), total: total }); }) return info; }, updateItems: function (updatedItems) { var item, depositRate, paymentsCurrency = false; if (updatedItems.settings != undefined) { settings.freeShippingLimit = updatedItems.settings.freeShippingLimit; settings.currency = updatedItems.settings.paymentsCurrency; settings.taxRate = updatedItems.settings.salesTax; settings.TaxApplicable = updatedItems.settings.TaxApplicable; settings.isCountrySupported = updatedItems.settings.isCountrySupported; settings.isfreeShippingCountry = updatedItems.settings.isfreeShippingCountry; settings.TargetFullInfo = updatedItems.TargetFullInfo; settings.SourceFullInfo = updatedItems.SourceFullInfo; settings.ShippingAddress = updatedItems.ShippingAddress; settings.Packages = updatedItems.Packages; settings.cartMessage = updatedItems.settings.cartMessage; settings.shoppingMessage = updatedItems.settings.shoppingMessage; settings.cartMessageEmailFlag = updatedItems.settings.cartMessageEmailFlag; settings.isLocalPickupPreferred = updatedItems.settings.isLocalPickupPreferred; settings.enableBackorders = updatedItems.settings.enableBackorders; settings.hasCoupon = updatedItems.settings.hasCoupon; if (settings.TargetFullInfo.feedCredit > 0 && settings.appliedCredit == undefined) { settings.appliedCredit = 0; } var grandTotalAfterTax = simpleCart.grandTotalBeforeCredit(); if (settings.appliedCredit > 0 && settings.appliedCredit > grandTotalAfterTax) { console.log([grandTotalAfterTax, settings.appliedCredit > grandTotalAfterTax]); settings.appliedCredit = grandTotalAfterTax; } if (settings.hasCoupon == 0) { settings.appliedCoupon = ''; } // settings.grandTotalAfterTax = grandTotalAfterTax; //console.log(settings.appliedCredit ,simpleCart.total()); } else { settings.appliedCredit = 0; settings.appliedCoupon = ''; } var removed = []; var changedToBackorder = []; if (updatedItems.rates != undefined && updatedItems.rates[0] != undefined) { settings.shippingRates = updatedItems.rates; var ServiceNames = jQuery.map(settings.shippingRates, function (n, i) { return n.ServiceName; }); var carrierIndex = $.inArray(settings.shippingServiceName, ServiceNames); if (!settings.shippingCarrier || carrierIndex === -1) { settings.shippingCarrier = updatedItems.rates[0].Total + '|' + updatedItems.rates[0].ServiceName; settings.shippingFlatRate = updatedItems.rates[0].Total; settings.shippingServiceName = updatedItems.rates[0].ServiceName; settings.shippingServiceId = updatedItems.rates[0].ServiceId; } else if (carrierIndex > -1) { settings.shippingCarrier = updatedItems.rates[carrierIndex].Total + '|' + updatedItems.rates[carrierIndex].ServiceName + '|' + updatedItems.rates[carrierIndex].ServiceId; settings.shippingFlatRate = updatedItems.rates[carrierIndex].Total; settings.shippingServiceName = updatedItems.rates[carrierIndex].ServiceName; settings.shippingServiceId = updatedItems.rates[carrierIndex].ServiceId; } if ((updatedItems.settings && updatedItems.settings.isfreeShippingCountry == 1 && settings.shippingServiceName.indexOf('Local') == -1)) { settings.shippingCarrier = '0|Free Shipping'; settings.shippingFlatRate = 0; settings.shippingServiceName = 'Free Shipping'; settings.shippingServiceId = 0; $('#CartShippingMethod').val(settings.shippingCarrier); } //console.log(settings.shippingCarrier ); } else { settings.shippingRates = {}; } $.each(updatedItems.items, function () { item = simpleCart.find(this.id); /*if (updatedItems.settings == undefined && !paymentsCurrency) { settings.currency = this.paymentsCurrency; paymentsCurrency = true; }*/ if (item.get("is_deposit") == 1) { if (item.get("deposit_type") == 'percentage') { depositRate = item.get("deposit_rate"); item.set("price", ((this.price * depositRate) / 100)); } } else { item.set("price", this.price); } item.set("pricing_rules", this.pricing_rules); item.set("instock", this.instock); item.set("before_price", this.before_price); item.set("is_tax_able", this.isTaxAble * settings.TaxApplicable); item.set("use_fixed_shipping", this.useFixedShipping); item.set("is_backorder", this.isBackorder); item.set("instock_quantity", this.instockQuantity); item.set("back_orders_quantity", this.backOrdersQuantity); item.set("tax_rate", this.itemTaxRate); item.set("is_free_shipping", this.isFreeShipping); item.set("max_quantity", this.quantity); //item.set("backorder_quantity", (this.backorder_quantity == undefined ? 0 : this.backorder_quantity)); if (item.get("quantity") > this.quantity) { item.set("quantity", this.quantity); } if (this.instock == 0) { item.set("quantity", this.instock); } if (this.instock == 0 && settings.enableBackorders == 0) { removed.push(item.get("name")); } /*else if (this.instock == 0 && item.get("is_backorder") == 0 && settings.enableBackorders == 1) { item.set("is_backorder", 1); item.set("max_quantity", 1000); changedToBackorder.push(item.get("name")); }*/ //console.log(this.itemShippingOptions,updatedItems.rates); if (updatedItems.rates != undefined) { item.set("selected_shipping_rate", 0); if (this.shippable >= 0) { item.set("shippable", this.shippable); } else { item.set("shippable", -1); } if (typeof this.itemShippingOptions === "object") { item.set("item_shipping_options", this.itemShippingOptions); } else { item.set("item_shipping_options", {}); } // console.log(item.get("item_shipping_options")); } //console.log(settings.currency); }); simpleCart.update(); return { removed: removed, changedToBackorder: changedToBackorder }; }, microficheTotalShipping: function () { var value = simpleCart.microficheItemsTotalValue(); var keyAr = []; if (value > 0) { for (const [key, elm] of Object.entries(window.microficheShipping)) { keyAr = key.split("-"); if (value >= keyAr[0] && value <= keyAr[1]) { return elm; } } } else { return value; } }, fixedShippingTotalShipping: function () { var value = simpleCart.fixedShippingItemsTotalValue(); var keyAr = []; var type; if (value > 0) { for (const [key, elm] of Object.entries(window.fixedShipping)) { keyAr = key.split("-"); if (key.indexOf('_type') == -1 && value >= keyAr[0] && value <= keyAr[1]) { type = window.fixedShipping[key + '_type'] !== undefined ? window.fixedShipping[key + '_type'] : 'fixed'; return type == 'fixed' ? elm : (value * (elm / 100)); } } } else { return 0; } }, itemsRulesValue: function (normalRules = false, otherRules = false, excludeCredit = false) { var value = 0; var appliedRules = simpleCart.itemsRules(normalRules, otherRules, excludeCredit); $.each(appliedRules, function () { value += this.value; }) return Number(parseFloat(value).toFixed(2)); }, microficheItemsTotalValue: function () { var value = 0; simpleCart.each(function (item, x) { if (item.get('is_microfiche') == 1 && item.get('shippable') == 3) { value += item.total(); } }); return value; }, microficheItemsCount: function () { var value = 0; simpleCart.each(function (item, x) { if (item.get('is_microfiche') == 1 && item.get('shippable') == 3) { value++; } }); return value; }, fixedShippingItemsTotalValue: function () { var value = 0; if (Object.keys(window.fixedShipping).length == 0) { return value; } else { simpleCart.each(function (item, x) { if (item.get('use_fixed_shipping') == 1 && item.get('shippable') == 3) { value += item.total(); } }); return value; } }, fixedShippingItemsCount: function () { var value = 0; if (Object.keys(window.fixedShipping).length == 0) { return value; } else { simpleCart.each(function (item, x) { if (item.get('use_fixed_shipping') == 1 && item.get('shippable') == 3) { value++; } }); return value; } }, itemsRules: function (normalRules = false, otherRules = false, excludeCredit = false) { var rules, index, appliedRules = {}; simpleCart.each(function (item, x) { rules = item.itemRules(normalRules, otherRules, excludeCredit); // console.log(rules); if (rules.length) { $.each(rules, function () { //console.log(this.label); if (appliedRules[this.label] == undefined) { appliedRules[this.label] = {}; appliedRules[this.label].value = 0; appliedRules[this.label].label = this.label; } if (this.add) { appliedRules[this.label].value += this.value; } else { appliedRules[this.label].value -= this.value; } }) } }); //console.log(appliedRules); return appliedRules; }, getDataArr: function () { var items = [], data = {}, carrier = '', id = 0; serviceId = 0; simpleCart.each(function (item, x) { id = item.id(); //var options = item.options() ; var shippable = item.get('shippable'); //carrier = shippable == 3 ? settings.shippingCarrier : (shippable == 0 ? '0|Contact for Pickup/Shipping' : (shippable == 1 ? '0|Free Shipping' : '0|Flat Rate Shipping')); carrier = shippable == 4 ? settings.shippingCarrier : shippable; //serviceId = shippable == 4 ? carrier.split('|')[2] : 0; data = { id: id, name: item.get('name'), price: item.price(), itemShipping: item.itemShipping(), itemTax: item.itemTax(), itemRulesValue: item.itemRulesValue(), itemCreditValue: Number(parseFloat(item.itemCreditValue()).toFixed(2)), grandTotal: Number(parseFloat(item.totalPerOneItem()).toFixed(2)), totalBefore: item.itemTotalPluseShipping(), quantity: item.quantity(), image: (item.get('image').indexOf('http') == -1 ? (location.origin + item.get('image')) : item.get('image')), url: item.get('url'), isDeposit: item.get('is_deposit'), depositRate: item.get('deposit_rate'), isBackorder: item.get("is_backorder"), instockQuantity: item.get("instock_quantity"), backOrdersQuantity: item.get("back_orders_quantity"), enableBackorders: (item.get("item_backorder") != undefined ? item.get("item_backorder") : settings.enableBackorders), depositType: item.get('deposit_type'), carrier: carrier, stock_number: item.get('stock_number'), before_price: item.get('before_price'), shipping_method: item.get('shipping_method'), shippable: item.get('shippable'), isTaxAble: item.get('is_tax_able'), useFixedShipping: item.get('use_fixed_shipping'), //serviceId: serviceId } items.push(data); }); return items; }, getDataShipableArr: function () { var items = [], data = {}, carrier = '', id = 0, serviceId = 0; simpleCart.each(function (item, x) { id = item.id(); //var options = item.options() ; var shippable = item.get('shippable'); //carrier = shippable == 3 ? settings.shippingCarrier : (shippable == 0 ? '0|Contact for Pickup/Shipping' : (shippable == 1 ? '0|Free Shipping' : '0|Flat Rate Shipping')); carrier = shippable == 4 ? settings.shippingCarrier : shippable; //serviceId = shippable == 4 ? carrier.split('|')[2] : 0; if (item.get('shippable') > 1) { data = { id: id, name: item.get('name'), price: item.price(), itemShipping: item.itemShipping(), itemTax: item.itemTax(), grandTotal: Number(parseFloat(item.totalPerOneItem()).toFixed(2)), totalBefore: item.itemTotalPluseShipping(), quantity: item.quantity(), image: item.get('image'), isBackorder: item.get("is_backorder"), url: item.get('url'), isDeposit: item.get('is_deposit'), enableBackorders: (item.get("item_backorder") != undefined ? item.get("item_backorder") : settings.enableBackorders), depositRate: item.get('deposit_rate'), depositType: item.get('deposit_type'), carrier: carrier, stock_number: item.get('stock_number'), before_price: item.get('before_price'), shipping_method: item.get('shipping_method'), shippable: item.get('shippable'), //serviceId: serviceId } items.push(data); } }); return items; }, nodeId: function () { var nodeId; simpleCart.each(function (item, x) { if (!nodeId) nodeId = item.get('node_id'); }); return nodeId; }, nodeLogo: function () { var nodeLogo; simpleCart.each(function (item, x) { if (!nodeLogo) nodeLogo = item.get('node_logo'); }); return nodeLogo ? nodeLogo + '?width=128' : 'https://stripe.com/img/documentation/checkout/marketplace.png'; }, // updating functions update: function () { simpleCart.save(); simpleCart.trigger("update"); }, init: function () { //console.trace(); console.log('inited'); simpleCart.load(); simpleCart.update(); simpleCart.ready(); }, // view management $: function (selector) { return new simpleCart.ELEMENT(selector); }, $create: function (tag) { return simpleCart.$(document.createElement(tag)); }, setupViewTool: function () { var members, member, context = window, engine; // Determine the "best fit" selector engine for (engine in selectorEngines) { if (Object.prototype.hasOwnProperty.call(selectorEngines, engine) && window[engine]) { members = selectorEngines[engine].replace("*", engine).split("."); member = members.shift(); if (member) { context = context[member]; } if (typeof context === "function") { // set the selector engine and extend the prototype of our // element wrapper class $engine = context; simpleCart.extend(simpleCart.ELEMENT._, selectorFunctions[engine]); return; } } } }, // return a list of id's in the cart ids: function () { var ids = []; simpleCart.each(function (item) { ids.push(item.id()); }); return ids; }, // storage save: function () { simpleCart.trigger('beforeSave'); var items = {}; //console.log(simpleCart.settings()); // save all the items simpleCart.each(function (item) { items[item.id()] = simpleCart.extend(item.fields(), item.options()); }); localStorage.setItem(namespace + "_items", JSON.stringify(items)); localStorage.setItem(namespace + "_settings", JSON.stringify(simpleCart.settings())); simpleCart.trigger('afterSave'); }, load: function () { // empty without the update sc_items = {}; var items = localStorage.getItem(namespace + "_items"); //console.log(simpleCart.settings); simpleCart.settings(JSON.parse(localStorage.getItem(namespace + "_settings"))); // console.log(simpleCart.settings()); if (!items) { return; } // we wrap this in a try statement so we can catch // any json parsing errors. no more stick and we // have a playing card pluckin the spokes now... // soundin like a harley. try { simpleCart.each(JSON.parse(items), function (item) { simpleCart.add(item, true); }); } catch (e) { simpleCart.error("Error Loading data: " + e); } simpleCart.trigger('load'); }, // ready function used as a shortcut for bind('ready',fn) ready: function (fn) { if (isFunction(fn)) { // call function if already ready already if (simpleCart.isReady) { fn.call(simpleCart); // bind if not ready } else { simpleCart.bind('ready', fn); } // trigger ready event } else if (isUndefined(fn) && !simpleCart.isReady) { simpleCart.trigger('ready'); simpleCart.isReady = true; } }, error: function (message) { var msg = ""; if (isString(message)) { msg = message; } else if (isObject(message) && isString(message.message)) { msg = message.message; } try { console.log("simpleCart(js) Error: " + msg); } catch (e) {} simpleCart.trigger('error', [message]); } }); /******************************************************************* * TAX AND SHIPPING *******************************************************************/ simpleCart.extend({ // TODO: tax and shipping tax: function () { //return Number(parseFloat((( (simpleCart.shipping() * 0) + simpleCart.itemsRulesValue()) * settings.taxRate) + simpleCart.totalTaxs()).toFixed(2)); return simpleCart.totalTaxs(); }, taxRate: function () { return settings.taxRate || 0; }, shipping: function (opt_custom_function) { // shortcut to extend options with custom shipping if (isFunction(opt_custom_function)) { simpleCart({ shippingCustom: opt_custom_function }); return; } var cost = settings.shippingQuantityRate * simpleCart.quantity() + settings.shippingTotalRate * simpleCart.total() + settings.shippingFlatRate; //console.log([cost,settings.shippingTotalRate ,settings.shippingFlatRate,settings.shippingQuantityRate ]); //console.log(cost); if (isFunction(settings.shippingCustom)) { cost += settings.shippingCustom.call(simpleCart); } //console.log(cost); simpleCart.each(function (item) { /* console.log([parseFloat(item.get('shipping') || 0), item.get('shippingQuantityRate') , item.get('shippingTotalRate') ,item.total(),item.get('shippingFlatRate'),item.get('selected_shipping_rate') , item.get('quantity'), (parseFloat(item.get('shippingFlatRate') || (item.get('selected_shipping_rate') * item.get('quantity')))) ]);*/ cost += Number(parseFloat(item.get('shipping') || 0)); cost += item.get('shippingQuantityRate') * item.get('quantity') + item.get('shippingTotalRate') * item.total(); + (parseFloat(item.get('shippingFlatRate', true, 0) || (item.get('selected_shipping_rate', true, 0) * item.get('quantity')))); //console.log([item.get('shippingFlatRate'),item.get('shippingFlatRate',0),item.get('shippingFlatRate',true),item.get('shippingFlatRate',false)]); }); //console.log(cost); return Number(parseFloat(cost)); }, carrier: function (val) { if (isUndefined(val)) { return settings.shippingCarrier; } else { var valAr = val.split('|'); settings.shippingFlatRate = Number(parseFloat(valAr[0])); settings.shippingServiceName = valAr[1]; settings.shippingServiceId = valAr[2]; settings.shippingCarrier = val; simpleCart.update(); return this; } }, settings: function (val) { //console.log(val); if (isUndefined(val) || val == null) { //console.log(settings.shippingRates,settings.shippingFlatRate); return { shippingCarrier: settings.shippingCarrier, shippingFlatRate: settings.shippingFlatRate, shippingServiceName: settings.shippingServiceName, shippingServiceId: settings.shippingServiceId, shippingRates: settings.shippingRates, enableBackorders: settings.enableBackorders, appliedCredit: settings.appliedCredit, hasCoupon: settings.hasCoupon, appliedCoupon: settings.appliedCoupon, }; } else { settings.shippingRates = val.shippingRates; settings.shippingCarrier = val.shippingCarrier; settings.shippingFlatRate = val.shippingFlatRate; settings.shippingServiceName = val.shippingServiceName; settings.shippingServiceId = val.shippingServiceId; settings.enableBackorders = val.enableBackorders; settings.enableBackorders = val.enableBackorders; settings.appliedCredit = val.appliedCredit; settings.hasCoupon = val.hasCoupon; settings.appliedCoupon = val.appliedCoupon; //settings.currency = val.currency; return this; } }, getSetting: function (key) { //console.log(key,); if (!isUndefined(key)) { return settings[key]; } else { return false; } }, getSettings: function () { return { TaxApplicable: settings.TaxApplicable, isCountrySupported: settings.isCountrySupported, cartMessage: settings.cartMessage, shoppingMessage: settings.shoppingMessage, cartMessageEmailFlag: settings.cartMessageEmailFlag, enableBackorders: settings.enableBackorders }; } }); /******************************************************************* * CART VIEWS *******************************************************************/ // built in cart views for item cells cartColumnViews = { attr: function (item, column) { //console.log([item, column,column.attr]); return item.get(column.attr) || ""; }, currency: function (item, column) { return simpleCart.toCurrency(item.get(column.attr) || 0); }, salePrice: function (item, column) { var before_price = item.get('before_price'); var price = item.get(column.attr); //console.log(before_price,price); if (before_price > 0) { return '
' + (simpleCart.toCurrency(before_price)) + '
' + simpleCart.toCurrency(price); } else { return simpleCart.toCurrency(price || 0); } }, link: function (item, column) { return "" + column.text + ""; }, decrement: function (item, column) { return "" + (column.text || "-") + ""; }, increment: function (item, column) { var disabled = (((item.get('quantity') >= item.get('max_quantity')) && item.get('is_backorder') == 0) || item.get('is_deposit') > 0) ? 'disabled' : ''; return "" + (column.text || "+") + ""; }, customQuantity: function (item, column) { //console.log(item.get('quantity'), item.get('backorder_quantity')); return (item.get('quantity') + item.get('backorder_quantity')); }, backorderQuantity: function (item, column) { //settings.enableBackorders == 1 && var hide = item.get('back_orders_quantity') > 0 ? '' : 'hide'; /* return '

In-Stock Quantity\ ' + item.get('quantity') + '\ Backorder Quantity\ ' + item.get('backorder_quantity') + '\

'; */ return '
Backordering ' + item.get('back_orders_quantity') + '
'; }, itemShippingOption: function (item, column) { var itemShippingOptions = Object.entries(item.get('item_shipping_options') || {}); var value = item.get('shippable'); var select = ''; var optionLength = itemShippingOptions.length; if (optionLength > 0) { for (const [key, elm] of itemShippingOptions) { select += '
\ \
'; if (optionLength == 1 && value == undefined) { item.set('shippable', key); } } } return '
' + select + '
'; }, carrier: function (item, column) { /* if (item.get('shippable') == 1) { item.set('carrier', settings.shippingCarrier); return settings.shippingServiceName; } else { item.set('carrier', '0|Please Select Shipping'); return '
Local Pickup Only
'; }*/ /*var rates = item.get('rates'); var carrier = item.get('carrier').split("|")[1]; var curRate, selected, value, text; var select = ''; return select;*/ }, image: function (item, column) { return ""; }, input: function (item, column) { return ""; }, quantityInput: function (item, column) { var maxQuantity = item.maxQuantity(); if (item.get("item_backorder") > 0) { maxQuantity = 10000; } return ""; //onchange='commitInputChange(this);' }, remove: function (item, column) { return "" + (column.text || "X") + ""; } }; // cart column wrapper class and functions function cartColumn(opts) { var options = opts || {}; return simpleCart.extend({ attr: "", label: "", view: "attr", text: "", className: "", hide: false }, options); } function cartCellView(item, column) { var viewFunc = isFunction(column.view) ? column.view : isString(column.view) && isFunction(cartColumnViews[column.view]) ? cartColumnViews[column.view] : cartColumnViews.attr; return viewFunc.call(simpleCart, item, column); } simpleCart.extend({ // write out cart writeCart: function (selector) { //console.log(selector); if (simpleCart.quantity() == 0) { var container = simpleCart.$(selector); var cart_container = '
\ Cart is empty!\
'; container.html(' ').html(cart_container); $('.cartCalculations').hide(); return cart_container; } else { $('.cartCalculations').show(); var TABLE = settings.cartStyle.toLowerCase(), isTable = TABLE === 'table', TR = isTable ? "tr" : "div", TH = isTable ? 'th' : 'div', TD = isTable ? 'td' : 'div', THEAD = isTable ? 'thead' : 'div', cart_container = simpleCart.$create(TABLE).addClass('table table-hover'), thead_container = simpleCart.$create(THEAD), header_container = simpleCart.$create(TR).addClass('headerRow'), container = simpleCart.$(selector), column, klass, label, x, xlen; //cartMessage cart_container.append(thead_container); thead_container.append(header_container); // create header for (x = 1, xlen = settings.cartColumns.length; x < xlen; x += 1) { column = cartColumn(settings.cartColumns[x]); klass = "item-" + (column.attr || column.view || column.label || column.text || "cell") + " " + column.className; label = column.label || ""; // append the header cell header_container.append( simpleCart.$create(TH).addClass(klass).html(label) ); } // cycle through the items simpleCart.each(function (item, y) { simpleCart.createCartRow(item, y, TR, TD, cart_container); }); container.html(' ').append(cart_container); return cart_container; } }, // generate a cart row from an item createCartRow: function (item, y, TR, TD, container) { var nameTd = settings.cartColumns[0]; var row = simpleCart.$create(TR) .addClass('itemRow row-' + y + " " + (y % 2 ? "even" : "odd")) .attr('id', "cartItem_" + item.id()), j, jlen, column, klass, content, cell; container.append(row); column = cartColumn(nameTd); klass = "item-" + (column.attr || (isString(column.view) ? column.view : column.label || column.text || "cell")) + " " + column.className; content = cartCellView(item, column); cell = simpleCart.$create('th').attr('colspan', (settings.cartColumns.length - 1)).addClass(klass).html(content); row.append(cell); var row = simpleCart.$create(TR) .addClass('itemRow row-' + y + " " + (y % 2 ? "even" : "odd")) .attr('id', "cartItem_" + item.id()), j, jlen, column, klass, content, cell; container.append(row); // cycle through the columns to create each cell for the item for (j = 1, jlen = settings.cartColumns.length; j < jlen; j += 1) { column = cartColumn(settings.cartColumns[j]); klass = "item-" + (column.attr || (isString(column.view) ? column.view : column.label || column.text || "cell")) + " " + column.className; content = cartCellView(item, column); cell = simpleCart.$create(TD).addClass(klass).html(content); row.append(cell); } return row; } }); /******************************************************************* * CART ITEM CLASS MANAGEMENT *******************************************************************/ simpleCart.Item = function (info) { // we use the data object to track values for the item var _data = {}, me = this; // cycle through given attributes and set them to the data object if (isObject(info)) { simpleCart.extend(_data, info); } // set the item id item_id += 1; _data.id = _data.id || item_id_namespace + item_id; /* console.log(_data.id,!isUndefined(sc_items[_data.id])); while (!isUndefined(sc_items[_data.id])) { item_id += 1; _data.id = item_id_namespace + item_id; } console.log(_data.id);*/ function checkQuantityAndPrice() { // check to make sure price is valid if (isString(_data.price)) { // trying to remove all chars that aren't numbers or '.' _data.price = parseFloat(_data.price.replace(simpleCart.currency().decimal, ".").replace(/[^0-9\.]+/ig, "")); } if (isNaN(_data.price)) { _data.price = 0; } if (_data.price < 0) { _data.price = 0; } // check to make sure quantity is valid if (isString(_data.quantity)) { _data.quantity = parseInt(_data.quantity.replace(simpleCart.currency().delimiter, ""), 10); } if (isNaN(_data.quantity)) { _data.quantity = 1; } if (_data.quantity <= 0) { me.remove(); } } // getter and setter methods to access private variables me.get = function (name, skipPrototypes, defaultVal) { var usePrototypes = !skipPrototypes; if (isUndefined(name)) { return name; } // return the value in order of the data object and then the prototype var val = isFunction(_data[name]) ? _data[name].call(me) : !isUndefined(_data[name]) ? _data[name] : isFunction(me[name]) && usePrototypes ? me[name].call(me) : !isUndefined(me[name]) && usePrototypes ? me[name] : _data[name]; if (isUndefined(val) && !isUndefined(defaultVal)) { return defaultVal; } else { return val; } }; me.set = function (name, value) { if (!isUndefined(name)) { _data[name.toLowerCase()] = value; if (name.toLowerCase() === 'price' || name.toLowerCase() === 'quantity') { checkQuantityAndPrice(); } } return me; }; me.equals = function (item) { return _data.id === item.get('id'); /* for (var label in _data) { if (Object.prototype.hasOwnProperty.call(_data, label)) { if (label !== 'quantity' && label !== 'id') { if (item.get(label) !== _data[label]) { //console.log([item.get(label),_data[label],label]); return false; } } } } return true;*/ }; me.options = function () { var data = {}; simpleCart.each(_data, function (val, x, label) { var add = true; simpleCart.each(me.reservedFields(), function (field) { if (field === label) { add = false; } return add; }); if (add) { data[label] = me.get(label); } }); return data; }; checkQuantityAndPrice(); }; simpleCart.Item._ = simpleCart.Item.prototype = { //Here // editing the item quantity increment: function (amount) { var diff = amount || 1; diff = parseInt(diff, 10); var newQuantity = this.quantity() + diff; if (this.isDeposit() > 0) { return null; } else { this.quantity(newQuantity); if (this.quantity() < 1) { this.remove(); return null; } return this; } }, decrement: function (amount) { var diff = amount || 1; return this.increment(-parseInt(diff, 10)); }, remove: function (skipUpdate) { var removeItemBool = simpleCart.trigger("beforeRemove", [sc_items[this.id()]]); if (removeItemBool === false) { return false; } delete sc_items[this.id()]; if (!skipUpdate) { simpleCart.update(); } return null; }, // special fields for items reservedFields: function () { return ['quantity', 'id', 'item_number', 'price', 'name', 'shipping', 'tax', 'tax_rate', 'backorder_quantity']; }, // return values for all reserved fields if they exist fields: function () { var data = {}, me = this; simpleCart.each(me.reservedFields(), function (field) { if (me.get(field)) { data[field] = me.get(field); } }); return data; }, // shortcuts for getter/setters. can // be overwritten for customization quantity: function (val) { //console.log(isUndefined(val) ? parseInt(this.get("quantity", true) || 1, 10) : this.set("quantity", val)); if (isUndefined(val)) { return parseInt(this.get("quantity", true) || 1, 10); } else { return this.set("quantity", val); } }, maxQuantity: function (val) { return isUndefined(val) ? parseInt(this.get("max_quantity", true)) : this.set("max_quantity", val); }, isDeposit: function (val) { return this.get("is_deposit") > 0 ? this.get("is_deposit") : 0; }, isBackorder: function (val) { return this.get("is_backorder") > 0 ? this.get("is_backorder") : 0; }, price: function (val) { var price = isUndefined(val) ? parseFloat((this.get("price", true).toString()).replace(simpleCart.currency().symbol, "").replace(simpleCart.currency().delimiter, "") || 1) : this.set("price", parseFloat((val).toString().replace(simpleCart.currency().symbol, "").replace(simpleCart.currency().delimiter, ""))); return Number(parseFloat(price)); }, id: function () { return this.get('id', false); }, total: function () { return Number(parseFloat(this.quantity() * this.price())); }, grandTotalPerItem: function () { var cost = this.price() + (this.get('tax') ? this.get('tax') : ((this.get('tax_rate') ? this.get('tax_rate') : settings.taxRate) * this.price())); cost += parseFloat(this.get('shipping') || 0); cost += this.get('shippingQuantityRate') * this.get('quantity') + this.get('shippingTotalRate') * this.price() + (parseFloat(this.get('shippingFlatRate') || (parseFloat(this.get('quantity') * this.get('selected_shipping_rate'))))); return Number(parseFloat(cost)); }, totalBeforeCredit: function () { var price = this.total(); //* this.quantity(); //var cost = parseFloat(price + (this.itemTax() / this.quantity())); //var cost = (price + parseFloat(this.itemShipping() / this.quantity())) + this.itemRulesValue(true, false); //var cost = price + this.itemRulesValue(false, false, true) + this.itemTax(); // console.log(this.itemRulesValue(false, false, true)); var cost = parseFloat(price + this.itemTax() + this.itemShipping() + this.itemRulesValue(false, false, true)); return Number(cost); }, totalBeforeTax: function () { var price = this.price() * this.quantity(); //var cost = parseFloat(price + (this.itemTax() / this.quantity())); //var cost = (price + parseFloat(this.itemShipping() / this.quantity())) + this.itemRulesValue(true, false); var cost = price + this.itemRulesValue(true, false, true); return Number(parseFloat(cost)); }, totalPerOneItem: function () { /* var price = this.price(); var cost = parseFloat((this.itemTax() / this.quantity())); cost += (parseFloat(this.itemShipping() / this.quantity())); cost += (parseFloat(this.itemRulesValue()) / this.quantity());*/ var price = this.total(); var cost = this.itemTax(); cost += this.itemShipping(); cost += this.itemRulesValue(); cost = parseFloat((price + cost) / this.quantity()); //[4174, 4174, 12.57, -4485.48, -298.91] /* console.log( [ price, parseFloat((this.itemTax() / this.quantity())), (parseFloat(this.itemShipping() / this.quantity())), (parseFloat(this.itemRulesValue()) / this.quantity()), Number(parseFloat(cost)) ]);*/ return Number(parseFloat(cost)); }, itemTotalPluseShipping: function () { //return (this.quantity() * this.price()) + (parseFloat(this.quantity() * this.get('selected_shipping_rate'))); return Number((this.quantity() * this.price()) + (parseFloat(this.get('selected_shipping_rate')))); }, itemShipping: function () { //return (parseFloat(this.quantity() * this.get('shippingFlatRate'))); //return 0; var cost = Number(parseFloat(((parseFloat(settings.shippingFlatRate)) / simpleCart.quantity()) * this.quantity())); //console.log(cost); return cost; }, itemTax: function () { if (this.get('is_deposit') == 1) { return 0; } else { //+ this.itemRulesValue() var taxAblAmount = ((this.total() + this.itemRulesValue(true, false))); //(this.itemShipping() * 0) if (this.get('use_fixed_shipping') || this.get('is_microfiche')) { taxAblAmount = (taxAblAmount + this.itemShipping()); } // console.log(taxAblAmount,settings.taxRate,this.get('is_tax_able')); var itemTax = taxAblAmount > 0 ? ((this.get('tax') ? this.get('tax') : ((this.get('tax_rate') ? this.get('tax_rate') : settings.taxRate) * taxAblAmount) * this.get('is_tax_able'))) : 0; // console.log(itemTax, taxAblAmount); itemTax = itemTax < 0 ? 0 : itemTax; return Number(parseFloat(itemTax)); } }, itemRulesValue: function (normalRules = false, otherRules = false, excludeCredit = false) { var appliedRules = this.itemRules(normalRules, otherRules, excludeCredit); //console.log(appliedRules); var value = 0; $.each(appliedRules, function () { // console.log(this,this.value); if (this.add) { value += parseFloat(this.value); } else { value -= parseFloat(this.value); } //value = Number(parseFloat(value)); }); return Number(parseFloat(value).toFixed(2)); }, itemRules: function (normalRules = false, otherRules = false, excludeCredit = false) { //console.log(normalRules,otherRules); var appliedRules = []; if (normalRules == false) { if (settings.appliedCredit > 0 && excludeCredit == false) { appliedRules.push({ label: 'Applied from Credit', value: this.itemCreditValue(), add: false }); } } if (otherRules == false) { // console.log(normalRules,otherRules); // console.trace(); // console.log(this.get('pricing_rules')); if (this.get('pricing_rules') && this.get('pricing_rules')[0] !== undefined) { appliedRules = this.generateRules(this.get('pricing_rules'), appliedRules); } if (this.get('is_microfiche') == 1) { var microficheItemShipping = parseFloat(simpleCart.microficheTotalShipping() / simpleCart.microficheItemsCount()); if (microficheItemShipping > 0) { appliedRules.push({ label: 'Flat Rate Shipping', //'Microfiche Shipping', value: parseFloat(microficheItemShipping), add: true }); } } else if (this.get('use_fixed_shipping') == 1) { // console.log([simpleCart.fixedShippingTotalShipping(),simpleCart.fixedShippingItemsCount()]); var fixedItemShipping = parseFloat(simpleCart.fixedShippingTotalShipping() / simpleCart.fixedShippingItemsCount()); if (fixedItemShipping > 0) { appliedRules.push({ label: 'Flat Rate Shipping', //'Dealer Shipping', value: fixedItemShipping, add: true }); } } } //console.log(appliedRules) return appliedRules; }, itemCreditValue: function () { settings.appliedCredit = parseFloat(settings.appliedCredit); var appliedCredit = parseFloat((settings.appliedCredit / simpleCart.grandTotalBeforeCredit()) * this.totalBeforeCredit()); if (appliedCredit > 0) { //return appliedCredit; return appliedCredit; } else { return 0; } }, generateRules: function (rules, appliedRules = []) { // var rules = this.get('pricing_rules'); if (rules && rules[0] !== undefined) { var value; var quantity = this.get('quantity'); var price = this.total(); //+ this.itemRulesValue(false, true); //var price = this.totalAfterTax(); $.each(rules, function (i, elm) { if (quantity >= elm.min_qty && quantity <= elm.max_qty) { if (elm.rule_type == 'percentage_discount') { value = parseFloat(price * (elm.value / 100)); //Number(parseFloat(price * (elm.value / 100)).toFixed(2)); appliedRules.push({ label: elm.label, value: value, add: false }); } else if (elm.rule_type == 'fixed_discount') { value = parseFloat(elm.value); //Number(parseFloat(elm.value).toFixed(2)); appliedRules.push({ label: elm.label, value: value, add: false }); } else if (elm.rule_type == 'percentage_surcharge') { value = parseFloat(price * (elm.value / 100)); //Number(parseFloat(price * (elm.value / 100)).toFixed(2)); appliedRules.push({ label: elm.label, value: value, add: true }); } else if (elm.rule_type == 'fixed_surcharge') { value = parseFloat(elm.value); //Number(parseFloat(elm.value).toFixed(2)); appliedRules.push({ label: elm.label, value: value, add: true }); } else if (elm.rule_type == 'percentage_discount_coupon' && elm.coupon && settings.appliedCoupon == elm.coupon) { value = parseFloat(price * (elm.value / 100)); //Number(parseFloat((price * (elm.value / 100))).toFixed(2)); appliedRules.push({ label: elm.label, value: value, add: false }); } else if (elm.rule_type == 'fixed_discount_coupon' && elm.coupon && settings.appliedCoupon == elm.coupon) { value = parseFloat(elm.value); // Number(parseFloat(elm.value).toFixed(2)); appliedRules.push({ label: elm.label, value: value, add: false }); } } }) } return appliedRules; //return {}; } }; /******************************************************************* * CHECKOUT MANAGEMENT *******************************************************************/ simpleCart.extend({ checkout: function () { if (settings.checkout.type.toLowerCase() === 'custom' && isFunction(settings.checkout.fn)) { settings.checkout.fn.call(simpleCart, settings.checkout); } else if (isFunction(simpleCart.checkout[settings.checkout.type])) { var checkoutData = simpleCart.checkout[settings.checkout.type].call(simpleCart, settings.checkout); // if the checkout method returns data, try to send the form if (checkoutData.data && checkoutData.action && checkoutData.method) { // if no one has any objections, send the checkout form if (false !== simpleCart.trigger('beforeCheckout', [checkoutData.data])) { simpleCart.generateAndSendForm(checkoutData); } } } else { simpleCart.error("No Valid Checkout Method Specified"); } }, extendCheckout: function (methods) { return simpleCart.extend(simpleCart.checkout, methods); }, generateAndSendForm: function (opts) { var form = simpleCart.$create("form"); form.attr('style', 'display:none;'); form.attr('action', opts.action); form.attr('method', opts.method); simpleCart.each(opts.data, function (val, x, name) { form.append( simpleCart.$create("input").attr("type", "hidden").attr("name", name).val(val) ); }); simpleCart.$("body").append(form); form.el.submit(); form.remove(); } }); simpleCart.extendCheckout({ PayPal: function (opts) { // account email is required if (!opts.email) { return simpleCart.error("No email provided for PayPal checkout"); } // build basic form options var data = { cmd: "_cart", upload: "1", currency_code: simpleCart.currency().code, business: opts.email, rm: opts.method === "GET" ? "0" : "2", tax_cart: Number(parseFloat(simpleCart.tax())), handling_cart: Number(parseFloat(simpleCart.shipping())), charset: "utf-8" }, action = opts.sandbox ? "https://www.sandbox.paypal.com/cgi-bin/webscr" : "https://www.paypal.com/cgi-bin/webscr", method = opts.method === "GET" ? "GET" : "POST"; // check for return and success URLs in the options if (opts.success) { data['return'] = opts.success; } if (opts.cancel) { data.cancel_return = opts.cancel; } if (opts.notify) { data.notify_url = opts.notify; } // add all the items to the form data simpleCart.each(function (item, x) { var counter = x + 1, item_options = item.options(), optionCount = 0, send; // basic item data data["item_name_" + counter] = item.get("name"); data["quantity_" + counter] = item.quantity(); data["amount_" + counter] = Number(parseFloat(item.price())); data["item_number_" + counter] = item.get("item_number") || counter; // add the options simpleCart.each(item_options, function (val, k, attr) { // paypal limits us to 10 options if (k < 10) { // check to see if we need to exclude this from checkout send = true; simpleCart.each(settings.excludeFromCheckout, function (field_name) { if (field_name === attr) { send = false; } }); if (send) { optionCount += 1; data["on" + k + "_" + counter] = attr; data["os" + k + "_" + counter] = val; } } }); // options count data["option_index_" + x] = Math.min(10, optionCount); }); // return the data for the checkout form return { action: action, method: method, data: data }; }, GoogleCheckout: function (opts) { // account id is required if (!opts.merchantID) { return simpleCart.error("No merchant id provided for GoogleCheckout"); } // google only accepts USD and GBP if (simpleCart.currency().code !== "USD" && simpleCart.currency().code !== "GBP") { return simpleCart.error("Google Checkout only accepts USD and GBP"); } // build basic form options var data = { // TODO: better shipping support for this google ship_method_name_1: "Shipping", ship_method_price_1: simpleCart.shipping(), ship_method_currency_1: simpleCart.currency().code, _charset_: '' }, action = "https://checkout.google.com/api/checkout/v2/checkoutForm/Merchant/" + opts.merchantID, method = opts.method === "GET" ? "GET" : "POST"; // add items to data simpleCart.each(function (item, x) { var counter = x + 1, options_list = [], send; data['item_name_' + counter] = item.get('name'); data['item_quantity_' + counter] = item.quantity(); data['item_price_' + counter] = item.price(); data['item_currency_ ' + counter] = simpleCart.currency().code; data['item_tax_rate' + counter] = item.get('tax_rate') || simpleCart.taxRate(); // create array of extra options simpleCart.each(item.options(), function (val, x, attr) { // check to see if we need to exclude this from checkout send = true; simpleCart.each(settings.excludeFromCheckout, function (field_name) { if (field_name === attr) { send = false; } }); if (send) { options_list.push(attr + ": " + val); } }); // add the options to the description data['item_description_' + counter] = options_list.join(", "); }); // return the data for the checkout form return { action: action, method: method, data: data }; }, AmazonPayments: function (opts) { // required options if (!opts.merchant_signature) { return simpleCart.error("No merchant signature provided for Amazon Payments"); } if (!opts.merchant_id) { return simpleCart.error("No merchant id provided for Amazon Payments"); } if (!opts.aws_access_key_id) { return simpleCart.error("No AWS access key id provided for Amazon Payments"); } // build basic form options var data = { aws_access_key_id: opts.aws_access_key_id, merchant_signature: opts.merchant_signature, currency_code: simpleCart.currency().code, tax_rate: simpleCart.taxRate(), weight_unit: opts.weight_unit || 'lb' }, action = "https://payments" + (opts.sandbox ? "-sandbox" : "") + ".amazon.com/checkout/" + opts.merchant_id, method = opts.method === "GET" ? "GET" : "POST"; // add items to data simpleCart.each(function (item, x) { var counter = x + 1, options_list = []; data['item_title_' + counter] = item.get('name'); data['item_quantity_' + counter] = item.quantity(); data['item_price_' + counter] = item.price(); data['item_sku_ ' + counter] = item.get('sku') || item.id(); data['item_merchant_id_' + counter] = opts.merchant_id; if (item.get('weight')) { data['item_weight_' + counter] = item.get('weight'); } if (settings.shippingQuantityRate) { data['shipping_method_price_per_unit_rate_' + counter] = settings.shippingQuantityRate; } // create array of extra options simpleCart.each(item.options(), function (val, x, attr) { // check to see if we need to exclude this from checkout var send = true; simpleCart.each(settings.excludeFromCheckout, function (field_name) { if (field_name === attr) { send = false; } }); if (send && attr !== 'weight' && attr !== 'tax') { options_list.push(attr + ": " + val); } }); // add the options to the description data['item_description_' + counter] = options_list.join(", "); }); // return the data for the checkout form return { action: action, method: method, data: data }; }, SendForm: function (opts) { // url required if (!opts.url) { return simpleCart.error('URL required for SendForm Checkout'); } // build basic form options var data = { currency: simpleCart.currency().code, shipping: simpleCart.shipping(), tax: simpleCart.tax(), taxRate: simpleCart.taxRate(), itemCount: simpleCart.find({}).length }, action = opts.url, method = opts.method === "GET" ? "GET" : "POST"; // add items to data simpleCart.each(function (item, x) { var counter = x + 1, options_list = [], send; data['item_name_' + counter] = item.get('name'); data['item_quantity_' + counter] = item.quantity(); data['item_price_' + counter] = item.price(); // create array of extra options simpleCart.each(item.options(), function (val, x, attr) { // check to see if we need to exclude this from checkout send = true; simpleCart.each(settings.excludeFromCheckout, function (field_name) { if (field_name === attr) { send = false; } }); if (send) { options_list.push(attr + ": " + val); } }); // add the options to the description data['item_options_' + counter] = options_list.join(", "); }); // check for return and success URLs in the options if (opts.success) { data['return'] = opts.success; } if (opts.cancel) { data.cancel_return = opts.cancel; } if (opts.extra_data) { data = simpleCart.extend(data, opts.extra_data); } // return the data for the checkout form return { action: action, method: method, data: data }; } }); /******************************************************************* * EVENT MANAGEMENT *******************************************************************/ eventFunctions = { // bind a callback to an event bind: function (name, callback) { if (!isFunction(callback)) { return this; } if (!this._events) { this._events = {}; } // split by spaces to allow for multiple event bindings at once var eventNameList = name.split(/ +/); // iterate through and bind each event simpleCart.each(eventNameList, function (eventName) { if (this._events[eventName] === true) { callback.apply(this); } else if (!isUndefined(this._events[eventName])) { this._events[eventName].push(callback); } else { this._events[eventName] = [callback]; } }); return this; }, // trigger event trigger: function (name, options) { var returnval = true, x, xlen; if (!this._events) { this._events = {}; } if (!isUndefined(this._events[name]) && isFunction(this._events[name][0])) { for (x = 0, xlen = this._events[name].length; x < xlen; x += 1) { returnval = this._events[name][x].apply(this, (options || [])); } } if (returnval === false) { return false; } return true; } }; // alias for bind eventFunctions.on = eventFunctions.bind; simpleCart.extend(eventFunctions); simpleCart.extend(simpleCart.Item._, eventFunctions); // base simpleCart events in options baseEvents = { beforeAdd: null, afterAdd: null, load: null, beforeSave: null, afterSave: null, update: null, ready: null, checkoutSuccess: null, checkoutFail: null, beforeCheckout: null, beforeRemove: null, quantityChange: null }; // extend with base events simpleCart(baseEvents); // bind settings to events simpleCart.each(baseEvents, function (val, x, name) { simpleCart.bind(name, function () { if (isFunction(settings[name])) { settings[name].apply(this, arguments); } }); }); /******************************************************************* * FORMATTING FUNCTIONS *******************************************************************/ simpleCart.extend({ toCurrency: function (number, opts) { var num = parseFloat(number), opt_input = opts || {}, _opts = simpleCart.extend(simpleCart.extend({ symbol: "$", decimal: ".", delimiter: ",", accuracy: 2, after: false }, simpleCart.currency()), opt_input), numParts = num.toFixed(_opts.accuracy).split("."), dec = numParts[1], ints = numParts[0]; ints = simpleCart.chunk(ints.reverse(), 3).join(_opts.delimiter.reverse()).reverse(); return (!_opts.after ? _opts.symbol : "") + ints + (dec ? _opts.decimal + dec : "") + (_opts.after ? _opts.symbol : ""); }, // break a string in blocks of size n chunk: function (str, n) { if (typeof n === 'undefined') { n = 2; } var result = str.match(new RegExp('.{1,' + n + '}', 'g')); return result || []; } }); // reverse string function String.prototype.reverse = function () { return this.split("").reverse().join(""); }; // currency functions simpleCart.extend({ currency: function (currency) { if (isString(currency) && !isUndefined(currencies[currency])) { settings.currency = currency; } else if (isObject(currency)) { currencies[currency.code] = currency; settings.currency = currency.code; } else { return currencies[settings.currency]; } } }); /******************************************************************* * VIEW MANAGEMENT *******************************************************************/ simpleCart.extend({ // bind outlets to function bindOutlets: function (outlets) { simpleCart.each(outlets, function (callback, x, selector) { if ($("." + namespace + "_" + selector).length) { simpleCart.bind('update', function () { simpleCart.setOutlet("." + namespace + "_" + selector, callback); }); } }); }, // set function return to outlet setOutlet: function (selector, func) { var val = func.call(simpleCart, selector); if (isObject(val) && val.el) { simpleCart.$(selector).html(' ').append(val); } else if (!isUndefined(val)) { simpleCart.$(selector).html(val); } }, // bind click events on inputs bindInputs: function (inputs) { simpleCart.each(inputs, function (info) { simpleCart.setInput("." + namespace + "_" + info.selector, info.event, info.callback); }); }, // attach events to inputs setInput: function (selector, event, func) { simpleCart.$(selector).live(event, func); } }); // class for wrapping DOM selector shit simpleCart.ELEMENT = function (selector) { this.create(selector); this.selector = selector || null; // "#" + this.attr('id'); TODO: test length? }; simpleCart.extend(selectorFunctions, { "MooTools": { text: function (text) { return this.attr(_TEXT_, text); }, html: function (html) { return this.attr(_HTML_, html); }, val: function (val) { return this.attr(_VALUE_, val); }, attr: function (attr, val) { if (isUndefined(val)) { return this.el[0] && this.el[0].get(attr); } this.el.set(attr, val); return this; }, remove: function () { this.el.dispose(); return null; }, addClass: function (klass) { this.el.addClass(klass); return this; }, removeClass: function (klass) { this.el.removeClass(klass); return this; }, append: function (item) { this.el.adopt(item.el); return this; }, each: function (callback) { if (isFunction(callback)) { simpleCart.each(this.el, function (e, i, c) { callback.call(i, i, e, c); }); } return this; }, click: function (callback) { if (isFunction(callback)) { this.each(function (e) { e.addEvent(_CLICK_, function (ev) { callback.call(e, ev); }); }); } else if (isUndefined(callback)) { this.el.fireEvent(_CLICK_); } return this; }, live: function (event, callback) { var selector = this.selector; if (isFunction(callback)) { simpleCart.$("body").el.addEvent(event + ":relay(" + selector + ")", function (e, el) { callback.call(el, e); }); } }, match: function (selector) { return this.el.match(selector); }, parent: function () { return simpleCart.$(this.el.getParent()); }, find: function (selector) { return simpleCart.$(this.el.getElements(selector)); }, closest: function (selector) { return simpleCart.$(this.el.getParent(selector)); }, descendants: function () { return this.find("*"); }, tag: function () { return this.el[0].tagName; }, submit: function () { this.el[0].submit(); return this; }, create: function (selector) { this.el = $engine(selector); } }, "Prototype": { text: function (text) { if (isUndefined(text)) { return this.el[0].innerHTML; } this.each(function (i, e) { $(e).update(text); }); return this; }, html: function (html) { return this.text(html); }, val: function (val) { return this.attr(_VALUE_, val); }, attr: function (attr, val) { if (isUndefined(val)) { return this.el[0].readAttribute(attr); } this.each(function (i, e) { $(e).writeAttribute(attr, val); }); return this; }, append: function (item) { this.each(function (i, e) { if (item.el) { item.each(function (i2, e2) { $(e).appendChild(e2); }); } else if (isElement(item)) { $(e).appendChild(item); } }); return this; }, remove: function () { this.each(function (i, e) { $(e).remove(); }); return this; }, addClass: function (klass) { this.each(function (i, e) { $(e).addClassName(klass); }); return this; }, removeClass: function (klass) { this.each(function (i, e) { $(e).removeClassName(klass); }); return this; }, each: function (callback) { if (isFunction(callback)) { simpleCart.each(this.el, function (e, i, c) { callback.call(i, i, e, c); }); } return this; }, click: function (callback) { if (isFunction(callback)) { this.each(function (i, e) { $(e).observe(_CLICK_, function (ev) { callback.call(e, ev); }); }); } else if (isUndefined(callback)) { this.each(function (i, e) { $(e).fire(_CLICK_); }); } return this; }, live: function (event, callback) { if (isFunction(callback)) { var selector = this.selector; document.observe(event, function (e, el) { if (el === $engine(e).findElement(selector)) { callback.call(el, e); } }); } }, parent: function () { return simpleCart.$(this.el.up()); }, find: function (selector) { return simpleCart.$(this.el.getElementsBySelector(selector)); }, closest: function (selector) { return simpleCart.$(this.el.up(selector)); }, descendants: function () { return simpleCart.$(this.el.descendants()); }, tag: function () { return this.el.tagName; }, submit: function () { this.el[0].submit(); }, create: function (selector) { if (isString(selector)) { this.el = $engine(selector); } else if (isElement(selector)) { this.el = [selector]; } } }, "jQuery": { passthrough: function (action, val) { if (isUndefined(val)) { return this.el[action](); } this.el[action](val); return this; }, text: function (text) { return this.passthrough(_TEXT_, text); }, html: function (html) { return this.passthrough(_HTML_, html); }, val: function (val) { return this.passthrough("val", val); }, append: function (item) { var target = item.el || item; this.el.append(target); return this; }, attr: function (attr, val) { if (isUndefined(val)) { return this.el.attr(attr); } this.el.attr(attr, val); return this; }, remove: function () { this.el.remove(); return this; }, addClass: function (klass) { this.el.addClass(klass); return this; }, removeClass: function (klass) { this.el.removeClass(klass); return this; }, each: function (callback) { return this.passthrough('each', callback); }, click: function (callback) { return this.passthrough(_CLICK_, callback); }, live: function (event, callback) { $engine(document).delegate(this.selector, event, callback); return this; }, parent: function () { return simpleCart.$(this.el.parent()); }, find: function (selector) { return simpleCart.$(this.el.find(selector)); }, closest: function (selector) { return simpleCart.$(this.el.closest(selector)); }, tag: function () { return this.el[0].tagName; }, descendants: function () { return simpleCart.$(this.el.find("*")); }, submit: function () { return this.el.submit(); }, create: function (selector) { this.el = $engine(selector); } } }); simpleCart.ELEMENT._ = simpleCart.ELEMENT.prototype; // bind the DOM setup to the ready event simpleCart.ready(simpleCart.setupViewTool); // bind the input and output events simpleCart.ready(function () { simpleCart.bindOutlets({ total: function () { // console.log(simpleCart.currency(),simpleCart.currency().code); return simpleCart.toCurrency(simpleCart.total()) + " " + simpleCart.currency().code; }, quantity: function () { return simpleCart.quantity(); }, items: function (selector) { //console.log(selector); simpleCart.writeCart(selector); }, tax: function () { return simpleCart.toCurrency(simpleCart.tax()); }, taxRate: function () { return simpleCart.taxRate(); }, shipping: function () { var shipping = simpleCart.shipping(); if (shipping == 0) { $('.shipping_parent').hide(); } return simpleCart.toCurrency(shipping); }, grandTotal: function () { // console.log(simpleCart.grandTotal()); return simpleCart.toCurrency(simpleCart.grandTotal()) + " " + simpleCart.currency().code; }, cartMessage: function () { return settings.cartMessage !== undefined && settings.cartMessage.length > 5 ? '
* ' + settings.cartMessage + "
" : ""; }, shoppingMessage: function () { if (settings.shoppingMessage !== undefined && settings.shoppingMessage.length > 5) { return '
\
\
Shipping Options
\
' + settings.shoppingMessage + '
\
\
'; } else { return ''; } }, beforeTaxTotal: function () { return simpleCart.toCurrency(simpleCart.grandTotalBeforeTax()) + " " + simpleCart.currency().code; }, outerGrandTotal: function () { return simpleCart.toCurrency(simpleCart.outerGrandTotal()) + " " + simpleCart.currency().code; }, selectShipping: function () { //console.log('selectShipping'); var curRate, selected, value, text; if ($('.simpleCart_selectShipping').size() == 0) return ''; if (settings.freeShippingLimit > 0) { var total = simpleCart.grandTotal(); } var disabled = settings.shippingRates[0] == undefined ? 'disabled' : ''; var select = '
'; // console.log(counter); if (counter < 2) { $('.simpleCart_selectShipping').hide(); } else { $('.simpleCart_selectShipping').show(); } //console.log(select,settings.shippingRates); return select; }, pricingRulesBefore: function () { var html = ''; var rules = simpleCart.itemsRules(true, false); $.each(rules, function (index, elm) { if (elm.value > 0) { html += '
+' + elm.label + ' : ' + simpleCart.toCurrency(elm.value) + '
'; } else { html += '
- ' + elm.label + ' : ' + (simpleCart.toCurrency(elm.value * -1)) + '
'; } }) return html; }, pricingRulesAfter: function () { var html = ''; var rules = simpleCart.itemsRules(false, true); $.each(rules, function (index, elm) { if (elm.value > 0) { html += '
+' + elm.label + ' : ' + simpleCart.toCurrency(elm.value) + '
'; } else { html += '
- ' + elm.label + ' : ' + (simpleCart.toCurrency(elm.value * -1)) + '
'; } }) return html; }, /*appliedCredit: function () { if (settings.TargetFullInfo != undefined && settings.TargetFullInfo.feedCredit > 0 && settings.appliedCredit > 0) { var html = ''; html += '
- Applied from Credit : ' + (simpleCart.toCurrency(settings.appliedCredit)) + '
'; return html; } else { return ''; } },*/ creditBox: function () { if (settings.TargetFullInfo != undefined && settings.TargetFullInfo.feedCredit > 0) { settings.appliedCredit = settings.appliedCredit == undefined ? 0 : settings.appliedCredit; var html = ''; /* html += '
\ \
\
\ \ \
\ \ \ \
\
';*/ html += '
\
\
\ \ \
\ \ \ \
\
'; return html; } else { return ''; } }, couponBox: function () { if (settings.hasCoupon) { var Coupon = settings.appliedCoupon != undefined && settings.appliedCoupon.trim().length > 2 ? settings.appliedCoupon : 0; var html = ''; /* html += '
\
Add a Coupon Code:
\
\
';*/ html += '
\
\
\ \ \
\ \ \
\
'; return html; } else { return ''; } }, quantityBox: function () { var itemId, quantity, max_quantity; var items = window.SellableItems.items; for (var prop in items) { itemId = prop; break; } if (itemId < 1) { return ''; } var cartItem = simpleCart.find(itemId); if (!Array.isArray(cartItem)) { quantity = cartItem.get('quantity'); max_quantity = cartItem.get('max_quantity'); } else { quantity = 1; max_quantity = window.SellableItems.items[itemId].quantity; } var html = '
\
\
\ \ \
\
\
\ \
\
'; return html; }, backordersAmount: function () { var itemId, quantity, max_quantity; var items = window.SellableItems.items; for (var prop in items) { itemId = prop; break; } if (itemId < 1) { return ''; } var cartItem = simpleCart.find(itemId); var html = '
' + cartItem.get('back_orders_quantity') + '
'; return html; } }); simpleCart.bindInputs([{ selector: 'checkout', event: 'click', callback: function () { simpleCart.checkout(); } }, { selector: 'empty', event: 'click', callback: function () { simpleCart.empty(); } }, { selector: 'increment', event: 'click', callback: function () { simpleCart.find(simpleCart.$(this).closest('.itemRow').attr('id').split("_")[1]).increment(); simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'quantityInput', event: 'change', callback: function () { var value = simpleCart.$(this).val(); var id = simpleCart.$(this).closest('.itemRow').attr('id').split("_")[1]; var item = simpleCart.find(id); //console.log(value); item.set('quantity', value); simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'decrement', event: 'click', callback: function () { simpleCart.find(simpleCart.$(this).closest('.itemRow').attr('id').split("_")[1]).decrement(); simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'itemShippingOption', event: 'change', callback: function () { var value = simpleCart.$(this).val(); var id = simpleCart.$(this).closest('.itemRow').attr('id').split("_")[1]; var item = simpleCart.find(id); //console.log(simpleCart.$(this).attr('data-method')); item.set('shippable', value); item.set('shipping_method', simpleCart.$(this).attr('data-method')); simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'carrier', event: 'change', callback: function () { //console.log('carrier'); var $input = simpleCart.$(this); simpleCart.carrier($input.val()); if (settings.appliedCredit) { simpleCart.trigger('quantityChange'); simpleCart.update(); } } }, { selector: 'credit', event: 'click', callback: function () { var $input = simpleCart.$(this); var appliedCredit = parseFloat($('#appliedCredit').val()); if (appliedCredit > settings.TargetFullInfo.feedCredit) { appliedCredit = settings.TargetFullInfo.feedCredit; } var grandTotalAfterTax = (simpleCart.grandTotalBeforeCredit()); if (appliedCredit > grandTotalAfterTax) { appliedCredit = grandTotalAfterTax; } settings.appliedCredit = Number(parseFloat(appliedCredit).toFixed(2)); //console.log(typeof settings.appliedCredit); simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'creditmax', event: 'click', callback: function () { var $input = simpleCart.$(this); console.log([simpleCart.grandTotal(), simpleCart.grandTotalBeforeCredit()]); var grandTotalAfterTax = (simpleCart.grandTotalBeforeCredit()); var appliedCredit = grandTotalAfterTax; if (appliedCredit > settings.TargetFullInfo.feedCredit) { appliedCredit = settings.TargetFullInfo.feedCredit; } if (appliedCredit > grandTotalAfterTax) { appliedCredit = grandTotalAfterTax; } settings.appliedCredit = appliedCredit; console.log(appliedCredit); simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'creditreset', event: 'click', callback: function () { var $input = simpleCart.$(this); settings.appliedCredit = 0; simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'coupon', event: 'click', callback: function () { var $input = simpleCart.$(this); var appliedCoupon = $('#appliedCoupon').val().trim(); settings.appliedCoupon = appliedCoupon; simpleCart.trigger('quantityChange'); simpleCart.update(); } }, { selector: 'couponremove', event: 'click', callback: function () { var $input = simpleCart.$(this); var appliedCoupon = ''; $('#appliedCoupon').prop('disabled', false); $('#appliedCoupon').val(appliedCoupon); settings.appliedCoupon = appliedCoupon; simpleCart.trigger('quantityChange'); simpleCart.update(); } } /* remove from cart */ , { selector: 'remove', event: 'click', callback: function () { simpleCart.find(simpleCart.$(this).closest('.itemRow').attr('id').split("_")[1]).remove(); simpleCart.trigger('quantityChange'); simpleCart.update(); } } /* cart inputs */ , { selector: 'input', event: 'change', callback: function () { var $input = simpleCart.$(this), $parent = $input.parent(), classList = $parent.attr('class').split(" "); simpleCart.each(classList, function (klass) { if (klass.match(/item-.+/i)) { var field = klass.split("-")[1]; simpleCart.find($parent.closest('.itemRow').attr('id').split("_")[1]).set(field, $input.val()); simpleCart.update(); return; } }); } } /* here is our shelfItem add to cart button listener */ , { selector: 'shelfItem .item_add', event: 'click', callback: function () { var $button = simpleCart.$(this), fields = {}; $button.closest("." + namespace + "_shelfItem").descendants().each(function (x, item) { var $item = simpleCart.$(item); // check to see if the class matches the item_[fieldname] pattern if ($item.attr("class") && $item.attr("class").match(/item_.+/) && !$item.attr('class').match(/item_add/)) { // find the class name simpleCart.each($item.attr('class').split(' '), function (klass) { var attr, val, type; // get the value or text depending on the tagName if (klass.match(/item_.+/)) { attr = klass.split("_")[1]; val = ""; switch ($item.tag().toLowerCase()) { case "input": case "textarea": case "select": type = $item.attr("type"); if (!type || ((type.toLowerCase() === "checkbox" || type.toLowerCase() === "radio") && $item.attr("checked")) || type.toLowerCase() === "text" || type.toLowerCase() === "number") { val = $item.val(); } break; case "img": val = $item.attr('src'); break; default: val = $item.text(); break; } if (val !== null && val !== "") { fields[attr.toLowerCase()] = fields[attr.toLowerCase()] ? fields[attr.toLowerCase()] + ", " + val : val; } } }); } }); // add the item simpleCart.add(fields); } } ]); }); /******************************************************************* * DOM READY *******************************************************************/ // Cleanup functions for the document ready method // used from jQuery /*global DOMContentLoaded */ if (document.addEventListener) { window.DOMContentLoaded = function () { document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false); simpleCart.init(); }; } else if (document.attachEvent) { window.DOMContentLoaded = function () { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if (document.readyState === "complete") { document.detachEvent("onreadystatechange", DOMContentLoaded); simpleCart.init(); } }; } // The DOM ready check for Internet Explorer // used from jQuery function doScrollCheck() { if (simpleCart.isReady) { return; } try { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch (e) { setTimeout(doScrollCheck, 1); return; } // and execute any waiting functions simpleCart.init(); } // bind ready event used from jquery function sc_BindReady() { // Catch cases where $(document).ready() is called after the // browser event has already occurred. if (document.readyState === "complete") { // Handle it asynchronously to allow scripts the opportunity to delay ready return setTimeout(simpleCart.init, 1); } // Mozilla, Opera and webkit nightlies currently support this event if (document.addEventListener) { // Use the handy event callback document.addEventListener("DOMContentLoaded", DOMContentLoaded, false); // A fallback to window.onload, that will always work window.addEventListener("load", simpleCart.init, false); // If IE event model is used } else if (document.attachEvent) { // ensure firing before onload, // maybe late but safe also for iframes document.attachEvent("onreadystatechange", DOMContentLoaded); // A fallback to window.onload, that will always work window.attachEvent("onload", simpleCart.init); // If IE and not a frame // continually check to see if the document is ready var toplevel = false; try { toplevel = window.frameElement === null; } catch (e) {} if (document.documentElement.doScroll && toplevel) { doScrollCheck(); } } } // bind the ready event sc_BindReady(); return simpleCart; }; window.simpleCart = generateSimpleCart(); }(window, document)); /************ JSON *************/ var JSON; JSON || (JSON = {}); (function () { function k(a) { return a < 10 ? "0" + a : a } function o(a) { p.lastIndex = 0; return p.test(a) ? '"' + a.replace(p, function (a) { var c = r[a]; return typeof c === "string" ? c : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) }) + '"' : '"' + a + '"' } function l(a, j) { var c, d, h, m, g = e, f, b = j[a]; b && typeof b === "object" && typeof b.toJSON === "function" && (b = b.toJSON(a)); typeof i === "function" && (b = i.call(j, a, b)); switch (typeof b) { case "string": return o(b); case "number": return isFinite(b) ? String(b) : "null"; case "boolean": case "null": return String(b); case "object": if (!b) return "null"; e += n; f = []; if (Object.prototype.toString.apply(b) === "[object Array]") { m = b.length; for (c = 0; c < m; c += 1) f[c] = l(c, b) || "null"; h = f.length === 0 ? "[]" : e ? "[\n" + e + f.join(",\n" + e) + "\n" + g + "]" : "[" + f.join(",") + "]"; e = g; return h } if (i && typeof i === "object") { m = i.length; for (c = 0; c < m; c += 1) typeof i[c] === "string" && (d = i[c], (h = l(d, b)) && f.push(o(d) + (e ? ": " : ":") + h)) } else for (d in b) Object.prototype.hasOwnProperty.call(b, d) && (h = l(d, b)) && f.push(o(d) + (e ? ": " : ":") + h); h = f.length === 0 ? "{}" : e ? "{\n" + e + f.join(",\n" + e) + "\n" + g + "}" : "{" + f.join(",") + "}"; e = g; return h } } if (typeof Date.prototype.toJSON !== "function") Date.prototype.toJSON = function () { return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + k(this.getUTCMonth() + 1) + "-" + k(this.getUTCDate()) + "T" + k(this.getUTCHours()) + ":" + k(this.getUTCMinutes()) + ":" + k(this.getUTCSeconds()) + "Z" : null }, String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function () { return this.valueOf() }; var q = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, p = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, e, n, r = { "\u0008": "\\b", "\t": "\\t", "\n": "\\n", "\u000c": "\\f", "\r": "\\r", '"': '\\"', "\\": "\\\\" }, i; if (typeof JSON.stringify !== "function") JSON.stringify = function (a, j, c) { var d; n = e = ""; if (typeof c === "number") for (d = 0; d < c; d += 1) n += " "; else typeof c === "string" && (n = c); if ((i = j) && typeof j !== "function" && (typeof j !== "object" || typeof j.length !== "number")) throw Error("JSON.stringify"); return l("", { "": a }) }; if (typeof JSON.parse !== "function") JSON.parse = function (a, e) { function c(a, d) { var g, f, b = a[d]; if (b && typeof b === "object") for (g in b) Object.prototype.hasOwnProperty.call(b, g) && (f = c(b, g), f !== void 0 ? b[g] = f : delete b[g]); return e.call(a, d, b) } var d, a = String(a); q.lastIndex = 0; q.test(a) && (a = a.replace(q, function (a) { return "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) })); if (/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) return d = eval("(" + a + ")"), typeof e === "function" ? c({ "": d }, "") : d; throw new SyntaxError("JSON.parse"); } })(); /************ HTML5 Local Storage Support *************/ (function () { if (!this.localStorage) if (this.globalStorage) try { this.localStorage = this.globalStorage } catch (e) {} else { var a = document.createElement("div"); a.style.display = "none"; document.getElementsByTagName("head")[0].appendChild(a); if (a.addBehavior) { a.addBehavior("#default#userdata"); var d = this.localStorage = { length: 0, setItem: function (b, d) { a.load("localStorage"); b = c(b); a.getAttribute(b) || this.length++; a.setAttribute(b, d); a.save("localStorage") }, getItem: function (b) { a.load("localStorage"); b = c(b); return a.getAttribute(b) }, removeItem: function (b) { a.load("localStorage"); b = c(b); a.removeAttribute(b); a.save("localStorage"); this.length = 0 }, clear: function () { a.load("localStorage"); for (var b = 0; attr = a.XMLDocument.documentElement.attributes[b++];) a.removeAttribute(attr.name); a.save("localStorage"); this.length = 0 }, key: function (b) { a.load("localStorage"); return a.XMLDocument.documentElement.attributes[b] } }, c = function (a) { return a.replace(/[^-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u37f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/g, "-") }; a.load("localStorage"); d.length = a.XMLDocument.documentElement.attributes.length } } })(); /*window.addEventListener('storage', (e) => { console.log('Key Changed before : '+e.key); if('simpleCart_quantityChange' == e.key) { simpleCart.init(); } });*/