Created
July 18, 2018 22:00
-
-
Save ca-santos/6240574263d0905e0fae16516ec11bc0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Fizzmod VTEX class | |
* @version 1.5.1 | |
* @copyright Fizzmod 2015 | |
* @author Marcos Casagrande | |
* | |
*/ | |
/* globals vtexjs,dataLayer,jQuery,google */ | |
"use strict"; | |
var Fizzmod = (function($, window, undefined) { | |
/** | |
* Fizzmod Class | |
* @class module:Fizzmod | |
* @module Fizzmod | |
*/ | |
function Fizzmod() {} | |
/** | |
* Fizzmod TagManager | |
* @class module:Fizzmod.TagManager | |
* @author Marcos Casagrande | |
*/ | |
if (!window.dataLayer) | |
window.dataLayer = []; | |
var TagManager = (function() { | |
var dataLayerEventsQueue = {}; | |
var GTMEventsCallback = {}; | |
var GTMOnceEventsCallback = {}; | |
/** Watched Properties map **/ | |
var watchedProperties = { | |
"event": ".event", //Dynamic event name dataLayer[0].event | |
"pageCategory": "page", | |
"categoryId": "category" //Static property name | |
}; | |
function dataLayerWatcher(dl, length, item) { | |
for (var property in watchedProperties) { | |
if (watchedProperties.hasOwnProperty(property)) { | |
/** If the dataLayer item has the watched property **/ | |
if (property in item) { | |
var prop = null; | |
var event = null; | |
if (watchedProperties[property].indexOf(".") === 0) { | |
prop = watchedProperties[property].substr(1, watchedProperties[property].length); | |
event = prop in item ? item[prop] : null; | |
} else { | |
event = watchedProperties[property]; | |
} | |
if (event) { | |
/** ONCE events **/ | |
if (event in GTMOnceEventsCallback) { | |
var j = GTMOnceEventsCallback[event].length; | |
while (j--) { | |
GTMOnceEventsCallback[event][j].call(null, event, item); | |
GTMOnceEventsCallback[event].splice(j, 1); | |
} | |
} | |
/** Event listener */ | |
if (event in GTMEventsCallback) { | |
var h = GTMEventsCallback[event].length; | |
while (h--) { | |
GTMEventsCallback[event][h].call(null, event, item); | |
} | |
} | |
dataLayerEventsQueue[event] = item; | |
} | |
} | |
} | |
} | |
} | |
if (window.dataLayer instanceof Array) { | |
/** Get already pushed events **/ | |
for (var i = 0, dl = window.dataLayer.length; i < dl; i++) { | |
for (var property in watchedProperties) { | |
if (watchedProperties.hasOwnProperty(property)) { | |
/** If the dataLayer item has the watched property **/ | |
if (property in window.dataLayer[i]) { | |
if (watchedProperties[property].indexOf(".") === 0) { | |
var prop = watchedProperties[property].substr(1, watchedProperties[property].length); | |
dataLayerEventsQueue[window.dataLayer[i][prop]] = window.dataLayer[i]; | |
} else { | |
dataLayerEventsQueue[watchedProperties[property]] = window.dataLayer[i]; | |
} | |
} | |
} | |
} | |
} | |
/** Modify data layer push with watcher function and call tag manager data layer push **/ | |
window.dataLayer.push = (function() { | |
var original = this.push; | |
return function() { | |
for (var i = 0, n = this.length, l = arguments.length; i < l; i++, n++) { | |
dataLayerWatcher(this, n, arguments[i]); | |
} | |
return original.apply(this, arguments); | |
}.bind(this); | |
}.bind(window.dataLayer))(); | |
} | |
function TagManager() {} | |
TagManager.prototype = { | |
/** | |
* Listen to the given tagmanager event | |
* @method module:Fizzmod.TagManager#on | |
* @param {string} events - The events to listen to | |
* @param {...function} callbacks - The callback that will be called upon entering the given event. | |
* @returns {object} Fizzmod.Tagmanager (chainable) | |
* @example | |
*Fizzmod.TagManager.on("homeView", function(){ | |
* //some function | |
*}, | |
*function(){ | |
* //other function | |
*}) | |
*/ | |
on: function() { | |
var events = Array.prototype.shift.call(arguments).split(" "); | |
var callbacks = Array.prototype.slice.call(arguments); | |
for (var i = 0, len = events.length; i < len; i++) { | |
if (!(events[i] in GTMEventsCallback)) | |
GTMEventsCallback[events[i]] = []; | |
GTMEventsCallback[events[i]] = GTMEventsCallback[events[i]].concat(callbacks); | |
var pos; | |
if (events[i] in dataLayerEventsQueue) { | |
var j = callbacks.length; | |
while (j--) { | |
callbacks[j].call(null, events[i], dataLayerEventsQueue[events[i]]); | |
} | |
} | |
} | |
return this; | |
}, | |
/** | |
* Listen to the given tagmanager event only ONCE | |
* @method module:Fizzmod.TagManager#once | |
* @param {string} events - The events to listen to | |
* @param {...function} callbacks - The callback that will be called upon entering the given event. | |
* @returns {object} Fizzmod.Tagmanager (chainable) | |
* @example | |
*Fizzmod.TagManager.on("homeView", function(){ | |
* //some function | |
*}, | |
*function(){ | |
* //other function | |
*}) | |
*/ | |
once: function() { | |
var events = Array.prototype.shift.call(arguments).split(" "); | |
var callbacks = Array.prototype.slice.call(arguments); | |
for (var i = 0, len = events.length; i < len; i++) { | |
if (events[i] in dataLayerEventsQueue) { | |
var j = callbacks.length; | |
while (j--) { | |
callbacks[j].call(null, events[i], dataLayerEventsQueue[events[i]]); | |
} | |
} else { | |
if (!(events[i] in GTMOnceEventsCallback)) | |
GTMOnceEventsCallback[events[i]] = []; | |
GTMOnceEventsCallback[events[i]] = GTMOnceEventsCallback[events[i]].concat(callbacks); | |
} | |
} | |
return this; | |
} | |
}; | |
return new TagManager(); | |
})(); | |
Fizzmod.prototype.TagManager = TagManager; | |
/** | |
Browser Polyfill | |
**/ | |
if (!Object.keys) { | |
Object.keys = function(obj) { | |
var keys = []; | |
for (var i in obj) { | |
if (obj.hasOwnProperty(i)) { | |
keys.push(i); | |
} | |
} | |
return keys; | |
}; | |
} | |
if (!Array.prototype.indexOf) { | |
Array.prototype.indexOf = function(obj, start) { | |
for (var i = (start || 0), j = this.length; i < j; i++) { | |
if (this[i] === obj) { | |
return i; | |
} | |
} | |
return -1; | |
}; | |
} | |
RegExp.escape = function(text) { | |
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); | |
}; | |
var _animationCallbacks = {}; | |
var supportsTouch = !!('ontouchstart' in window || navigator.msMaxTouchPoints); | |
/** VTEX APIs URL **/ | |
var API_URL = { | |
SEARCH: "/api/catalog_system/pub/products/search/" | |
}; | |
var Cache = {}; | |
/** | |
* Fizzmod Utils | |
* @class module:Fizzmod.Utils | |
* @author Marcos Casagrande | |
*/ | |
var Utils = { | |
currency: null, | |
/** | |
* Get the VTEX server time | |
* @method module:Fizzmod.Utils#getServerTime | |
* @access public | |
* @param {function} callback - The callback to call when the request finishes. The callback will a javascript Date object. | |
* @returns {promise} - jquery Ajax promise | |
* @example | |
*Fizzmod.Utils.getServerTime(function(date){ | |
* console.log(date.getFullYear()); | |
*}); | |
*/ | |
getServerTime: function(callback) { | |
return $.ajax({ | |
url: "/no-cache/HoraAtualServidor.aspx", | |
success: function(response) { | |
var monthBr = ["jan", "fev", "mar", "abr", "mai", "jun", "jul", "ago", "set", "out", "nov", "dez"]; | |
var time = response.match(/([0-9]+):([0-5][0-9]):([0-5][0-9])/)[0]; | |
var day = parseInt(response.match(/[a-z]{3} ([0-9]{1,2})/)[1]); | |
var month = monthBr.indexOf(response.match(/[a-z]{3}/)[0]) + 1; | |
var year = parseInt(response.match(/[0-9]{4}/)[0]); | |
if (day < 10) | |
day = "0" + day; | |
if (month < 10) | |
month = "0" + month; | |
if(typeof callback == "function") { | |
callback.call(null, new Date(year + "/" + month + "/" + day + " " + time)); | |
} | |
} | |
}); | |
}, | |
/** | |
* Get a specific order data. | |
* @method module:Fizzmod.Utils#getOrder | |
* @param {string} order - The order ID | |
* @access public | |
* @returns {promise} - jquery Ajax promise | |
*/ | |
getOrder: function(order) { | |
return $.ajax({ | |
type: "GET", | |
url: "/api/checkout/pub/orders/" + order | |
}); | |
}, | |
/** | |
* Get the original VTEX image source from a thumb | |
* @method module:Fizzmod.Utils#getOriginalImage | |
* @access public | |
* @param {string} src - The source of the thumb | |
* @returns {string} The original image source | |
* @example | |
*Fizzmod.Utils.getOriginalImage('http://fizzmod.vteximg.com.br/arquivos/ids/155242-292-292/image.png'); | |
* //http://fizzmod.vteximg.com.br/arquivos/ids/155242/image.png | |
*/ | |
getOriginalImage: function(src) { | |
return typeof src == 'string' ? src.replace(/(ids\/[0-9]+)-([0-9-]+)\//, "$1/") : src; | |
}, | |
/** | |
* Change the width & height from a given VTEX image source | |
* @method module:Fizzmod.Utils#getResizedImage | |
* @access public | |
* @param {string} src - The source of the image | |
* @param {int|string} width - The new image with | |
* @param {int|string} height - The new image height | |
* @returns {string} The resized image source | |
* @example | |
* //Given an image thumb source | |
*Fizzmod.Utils.getResizedImage('http://fizzmod.vteximg.com.br/arquivos/ids/155242-292-292/image.png', 500, 600); | |
* //Output: http://fizzmod.vteximg.com.br/arquivos/ids/155242-500-600/image.png | |
* | |
* //Given a full image source | |
* Fizzmod.Utils.getResizedImage('http://fizzmod.vteximg.com.br/arquivos/ids/155242/image.png', 100, 100); | |
* //Output: http://fizzmod.vteximg.com.br/arquivos/ids/155242-100-100/image.png | |
*/ | |
getResizedImage: function(src, width, height) { | |
if (width === undefined || height === undefined || typeof src != 'string') | |
return src; | |
src = src.replace(/(?:ids\/[0-9]+)-([0-9]+)-([0-9]+)\//, function(match, matchedWidth, matchedHeight) { | |
return match.replace("-" + matchedWidth + "-" + matchedHeight, "-" + width + "-" + height); | |
}); | |
return src.replace(/(ids\/[0-9]+)\//, "$1-" + width + "-" + height + "/"); | |
}, | |
/** | |
* Check if the given price is valid | |
* @method module:Fizzmod.Utils#isValidPrice | |
* @access public | |
* @param {string} price - The price to check | |
* @param {string} [thousand=","] - The thousands separator | |
* @param {string} [decimal="."] - The decimal separator | |
* @param {int} [decimalLength=2] - The decimal length | |
* @returns {boolean} | |
* | |
*/ | |
isValidPrice: function(price, thousands, decimal, decimalLength) { | |
//^[0-9]{1,3}(?:\,(?:(?:[0-9]{3}(?:,|))+))?(?:\.[0-9]{0,2})?$ | |
thousands = thousands || ","; | |
decimal = decimal || "."; | |
decimalLength = typeof decimalLength !== 'number' ? 2 : decimalLength; | |
var regex = new RegExp("^[0-9]{1,3}(?:\\" + thousands + "(?:(?:[0-9]{3}(?:" + thousands + "|))+))?(?:\\" + decimal + "[0-9]{0," + decimalLength + "})?$"); | |
return regex.test(price.toString()); | |
}, | |
/** | |
* Get a product by product Id using VTEX API Search | |
* @method module:Fizzmod.Utils#getProduct | |
* @access public | |
* @param {string/int} product - The product Id | |
* @returns {Promise} - Promise | |
* | |
*/ | |
getProduct: function(product) { | |
if (!("products" in Cache)) | |
Cache.products = {}; | |
if (typeof Cache.products[product] !== "undefined" && typeof Cache.products[product].done !== "undefined") { //Return promise | |
return Cache.products[product]; | |
} | |
return $.Deferred(function() { | |
var def = this; | |
if (typeof Cache.products[product] !== "undefined") //Item is in cache, return it. | |
return def.resolve(Cache.products[product]); | |
Cache.products[product] = def; | |
$.ajax({ | |
url: API_URL.SEARCH + "?fq=productId:" + product, | |
dataType: "json", | |
success: function(response) { | |
Cache.products[product] = response; | |
def.resolve(response); | |
}, | |
error: function() { | |
Cache.products[product] = undefined; | |
def.reject(); | |
} | |
}); | |
}).promise(); | |
}, | |
/** | |
* Get a product by sku Id using VTEX API Search | |
* @method module:Fizzmod.Utils#getSKU | |
* @access public | |
* @param {string/int} sku - The sku Id | |
* @returns {Promise} - Promise | |
* | |
*/ | |
getSKU: function(sku) { | |
if (!("skus" in Cache)) | |
Cache.skus = {}; | |
if (typeof Cache.skus[sku] !== "undefined" && typeof Cache.skus[sku].done !== "undefined") { //Return promise | |
return Cache.skus[sku]; | |
} | |
return $.Deferred(function() { | |
var def = this; | |
if (typeof Cache.skus[sku] !== "undefined") //Item is in cache, return it. | |
return def.resolve(Cache.skus[sku]); | |
Cache.skus[sku] = def; | |
$.ajax({ | |
url: API_URL.SEARCH + "?fq=skuId:" + sku, | |
dataType: "json", | |
success: function(response) { | |
Cache.skus[sku] = response; | |
def.resolve(response); | |
}, | |
error: function() { | |
Cache.skus[sku] = undefined; | |
def.reject(); | |
} | |
}); | |
}).promise(); | |
}, | |
/** | |
* get country file | |
* @method module:Fizzmod.Utils#getCountryFile | |
* @access public | |
* @param {string} [countryCode="ARG"] - The country code | |
* @returns {promise} | |
* @example | |
*Fizzmod.Utils.getCountryFile().done(function(file){ | |
* console.log(file); | |
* //https://io.vtex.com.br/front.shipping-data/2.10.2/script/rule/CountryARG.js | |
*}); | |
*/ | |
getCountryFile: function(countryCode) { | |
return $.Deferred(function() { | |
var _def = this; | |
var bucketSearchUrl = "https://io.vtex.com.br/?prefix=front.shipping-data"; | |
var fileUrlPrefix = "https://io.vtex.com.br/"; | |
if (typeof countryCode == "undefined") countryCode = "ARG"; | |
$.ajax({ | |
url: bucketSearchUrl, | |
type: "get", | |
dataType: "xml", | |
success: function(res) { | |
var file = false; | |
$(res).find("Contents Key").each(function() { | |
if (this.innerHTML.match("front.shipping-data/[0-9\.]+/script/rule/Country" + countryCode + ".js$")) { | |
file = this.innerHTML; | |
} | |
}); | |
if (file) _def.resolve(fileUrlPrefix + file); | |
else _def.reject(); | |
}, | |
error: function() { | |
_def.reject(); | |
} | |
}); | |
}).promise(); | |
}, | |
/** | |
* Add SKU's to cart | |
* @method module:Fizzmod.Utils#addSKU | |
* @access public | |
* @param {int|object} SKUs - A key/value pair indicating SKU & quantity to add | |
* @param {int|string} [salesChannel=1] - The sales channel | |
* @param {int|string} [seller=1] - The seller | |
* @param {object} [extra=""] - Extra url parameters, utmi_cp | |
* @param {string} [url] - The Host URL, used only for multiple sites sharing same checkout. Ie: http://example.com - Without trailing slash | |
* @returns {promise} jQuery Ajax Promise | |
* @example | |
*Fizzmod.Utils.addSKU({ sku1: qty1, sku2: qty2 }); | |
*Fizzmod.Utils.addSKU(sku); //default quantity 1 | |
*Fizzmod.Utils.addSKU({ sku1: qty1 }, '1', '1', { utmi_cp: 2, utmi_campaign: 'google' }); | |
*/ | |
addSKU: function(SKUs, salesChannel, seller, extra, url) { | |
var qty = 1; | |
var params = ""; | |
salesChannel = salesChannel || 1; | |
seller = seller || 1; | |
if (typeof SKUs == "object") { | |
for (var sku in SKUs) | |
params += "sku=" + sku + "&qty=" + SKUs[sku] + "&seller=" + seller + "&"; | |
params = params.substring(0, params.length - 1); | |
} else { | |
params = "sku=" + SKUs + "&qty=" + qty + "&seller=" + seller; | |
} | |
return $.ajax({ | |
url: (url || "") + "/checkout/cart/add?" + params + "&redirect=false&sc=" + salesChannel + Utils.serialize(extra, true) | |
}); | |
}, | |
/** | |
* Remove the given SKU's from the cart | |
* @method module:Fizzmod.Utils#removeSKU | |
* @param {int/Array} skus - The sku's to remove. | |
* @access public | |
* @returns {promise} Order Form | |
* @example | |
*Fizzmod.Utils.removeSKU([123,125]).done(function(orderForm){ console.log(orderForm); }); | |
*/ | |
removeSKU: function(skus) { | |
skus = skus instanceof Array ? skus : [skus]; | |
skus = skus.map(function(sku) { | |
return sku | 0; | |
}); //String to int conversion | |
return $.Deferred(function() { | |
var def = this; | |
vtexjs.checkout.getOrderForm().then(function(orderForm) { | |
var itemsToRemove = []; | |
for (var i = 0, len = orderForm.items.length; i < len; i++) { | |
if (~skus.indexOf(orderForm.items[i].id | 0)) { | |
orderForm.items[i].index = i; | |
itemsToRemove.push(orderForm.items[i]); | |
} | |
} | |
return vtexjs.checkout.removeItems(itemsToRemove).done(function(orderForm) { | |
def.resolve(orderForm); | |
}); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Empty the cart | |
* @method module:Fizzmod.Utils#emptyCart | |
* @access public | |
* @returns {promise} Order Form | |
* @example | |
*Fizzmod.Utils.emptyCart().done(function(orderForm){ console.log(orderForm); }); | |
*/ | |
emptyCart: function() { | |
return $.Deferred(function() { | |
var def = this; | |
vtexjs.checkout.getOrderForm().done(function(orderForm) { | |
if (orderForm.items.length) { | |
return vtexjs.checkout.removeAllItems(orderForm.items).done(function(orderForm) { | |
def.resolve(orderForm); | |
}); | |
} | |
return def.resolve(orderForm); | |
}).fail(function() { | |
def.reject(); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Check if the user is logged into VTEX | |
* @method module:Fizzmod.Utils#checkLogin | |
* @access public | |
* @returns {promise} jQuery Ajax Promise | |
*/ | |
checkLogin: function() { | |
return $.Deferred(function() { | |
var def = this; | |
$.ajax({ | |
type: "GET", | |
url: "/no-cache/profileSystem/getProfile", | |
data: {}, | |
success: function(res) { | |
if (typeof res.IsUserDefined == "undefined" || !res.IsUserDefined) { | |
def.reject(res); | |
} else def.resolve(res); | |
}, | |
error: function() { | |
def.reject(); | |
} | |
}); | |
}).promise(); | |
}, | |
/** | |
* Get category tree | |
* @method module:Fizzmod.Utils#getCategories | |
* @param [depth=50] - The tree depth | |
* @param [categoryId] - Return the specific Category | |
* @access public | |
* @returns {promise} Promise | |
*/ | |
getCategories: function(depth, categoryId) { | |
return $.Deferred(function() { | |
var def = this; | |
$.ajax({ | |
type: "GET", | |
url: "/api/catalog_system/pub/category/tree/" + (depth || 50), | |
dataType: "json", | |
headers: { | |
accept: "application/json", | |
contentType: "application/json; charset=utf-8", | |
}, | |
success: function(response) { | |
if (typeof categoryId !== "undefined") | |
def.resolve(Utils.objectSearch(response, { | |
id: categoryId | |
})); | |
else def.resolve(response); | |
}, | |
error: function() { | |
def.reject(); | |
} | |
}); | |
}).promise(); | |
}, | |
/** | |
* Get Search total items | |
* @method module:Fizzmod.Utils#getCategories | |
* @param [query] - API Search query string | |
* @access public | |
* @returns {promise} | |
*/ | |
getSearchTotalItems: function(query) { | |
var deferred = $.Deferred(); | |
$.ajax({ | |
url: "/api/catalog_system/pub/products/search/" + (query || ""), | |
type: "GET", | |
headers: { | |
resources: '0-0' | |
}, | |
success: function(response, status, request) { | |
deferred.resolve(request.getResponseHeader("resources").split("/").pop()); | |
}, | |
error: function() { | |
deferred.reject(); | |
} | |
}); | |
return deferred.promise(); | |
}, | |
/** | |
* Add an animation listener for the given animation name | |
* @access public | |
* @method module:Fizzmod.Utils#addAnimation | |
* @param {object} SKUs - The source of the image | |
* @param {int|string} [salesChannel=1] - The sales channel | |
* @param {int|string} [seller=1] - The seller | |
* @example | |
*Fizzmod.Utils.addAnimation('nodeInserted', myFunction); | |
* | |
*/ | |
addAnimation: function(name, callback) { | |
if (!Object.keys(_animationCallbacks).length) { | |
document.addEventListener("animationstart", function(e) { | |
if (e.animationName in _animationCallbacks) { | |
for (var i = 0, animationLength = _animationCallbacks[e.animationName].length; i < animationLength; i++) { | |
_animationCallbacks[e.animationName][i].call(null, e); | |
} | |
} | |
}); | |
document.addEventListener("webkitAnimationStart", function(e) { | |
if (e.animationName in _animationCallbacks) { | |
for (var i = 0, animationLength = _animationCallbacks[e.animationName].length; i < animationLength; i++) { | |
_animationCallbacks[e.animationName][i].call(null, e); | |
} | |
} | |
}); | |
document.addEventListener("MSAnimationStart", function(e) { | |
if (e.animationName in _animationCallbacks) { | |
for (var i = 0, animationLength = _animationCallbacks[e.animationName].length; i < animationLength; i++) { | |
_animationCallbacks[e.animationName][i].call(null, e); | |
} | |
} | |
}); | |
document.addEventListener("oAnimationStart", function(e) { | |
if (e.animationName in _animationCallbacks) { | |
for (var i = 0, animationLength = _animationCallbacks[e.animationName].length; i < animationLength; i++) { | |
_animationCallbacks[e.animationName][i].call(null, e); | |
} | |
} | |
}); | |
document.addEventListener("mozAnimationStart", function(e) { | |
if (e.animationName in _animationCallbacks) { | |
for (var i = 0, animationLength = _animationCallbacks[e.animationName].length; i < animationLength; i++) { | |
_animationCallbacks[e.animationName][i].call(null, e); | |
} | |
} | |
}); | |
} | |
if (!(_animationCallbacks[name] instanceof Array)) | |
_animationCallbacks[name] = []; | |
_animationCallbacks[name].push(callback); | |
}, | |
/** | |
* set a cookie | |
* @method module:Fizzmod.Utils#setCookie | |
* @access public | |
* @param {string} cname - The name of the cookie | |
* @param {mixed} cvalue - The value of the cookie, if the value is an object, it will be JSON encoded | |
* @param {int} [cvalue] - Expiration days, if not set the cookie will last through the session only. | |
* @returns {void} | |
*/ | |
setCookie: function(cname, cvalue, exdays) { | |
var expires = ""; | |
cvalue = typeof cvalue == 'object' ? JSON.stringify(cvalue) : cvalue; | |
if (!isNaN(exdays)) { | |
var d = new Date(); | |
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); | |
expires = "expires=" + d.toGMTString() + ";"; | |
} | |
document.cookie = cname + "=" + cvalue + "; " + expires + "path=/"; | |
}, | |
/** | |
* get a cookie | |
* @method module:Fizzmod.Utils#getCookie | |
* @access public | |
* @param {string} cname - The name of the cookie to retrieve | |
* @returns {string/object} The cookie value. If the value is a valid JSON it will be decoded into an object. | |
*/ | |
getCookie: function(cname) { | |
var name = cname + "="; | |
var ca = document.cookie.split(';'); | |
for (var i = 0; i < ca.length; i++) { | |
var c = ca[i]; | |
while (c.charAt(0) == ' ') | |
c = c.substring(1); | |
if (c.indexOf(name) === 0) { | |
var value = c.substring(name.length, c.length); | |
return Utils.isJSON(value) ? JSON.parse(value) : value; | |
} | |
} | |
return ""; | |
}, | |
/** | |
* delete a cookie | |
* @method module:Fizzmod.Utils#deleteCookie | |
* @access public | |
* @param {string} cname - The name of the cookie to delete | |
* @returns {void} | |
*/ | |
deleteCookie: function(cname) { | |
this.setCookie(cname, "", -1); | |
}, | |
/** | |
* Check if a string is a valid mail | |
* @method module:Fizzmod.Utils#isEmail | |
* @access public | |
* @param {string} email - The string to check | |
* @returns {boolean} | |
*/ | |
isEmail: function(email) { | |
return /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(email); | |
}, | |
/** | |
* Check if a string is a valid URL | |
* @method module:Fizzmod.Utils#isURL | |
* @access public | |
* @param {string} URL - The string to check | |
* @returns {boolean} | |
*/ | |
isURL: function(URL) { | |
return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(URL); | |
}, | |
/** | |
* Check if a string is a valid JSON | |
* @method module:Fizzmod.Utils#isJSON | |
* @access public | |
* @param {string} json - The string to check | |
* @returns {boolean} | |
*/ | |
isJSON: function(json) { | |
try{ | |
JSON.parse(json); | |
return true; | |
}catch(e){ | |
return false; | |
} | |
}, | |
/** | |
* Validate RUT (Chile) | |
* @method module:Fizzmod.Utils#isRUT | |
* @access public | |
* @param {string} rut - The rut to validate | |
* @returns {boolean} | |
*/ | |
isRUT: function(rut) { | |
if (rut.indexOf("-") > -1) { | |
rut = rut.replace(/\./g, "").toUpperCase(); | |
rut = rut.split("-"); | |
if (rut.length == 2) { | |
var rutNum = rut[0]; | |
var rutLast = rut[1]; | |
if (rutLast.length < 3 && rutLast.match(/[0-9kK]/g)) { | |
var sum = 0; | |
var m = 2; | |
for (var i = (rutNum.length - 1); i >= 0; i--) { | |
sum += rutNum[i] * m; | |
m = m == 7 ? 2 : m + 1; | |
} | |
var mod = parseInt(sum / 11); | |
var res = sum - (11 * mod); | |
var last = 11 - res; | |
if (last.toString().length > 2) return false; | |
last = last == 11 ? 0 : (last == 10 ? "K" : last); | |
return last == rutLast; | |
} | |
} | |
} | |
return false; | |
}, | |
/** | |
* Validate RUC (Perú) | |
* @method module:Fizzmod.Utils#isRUC | |
* @access public | |
* @param {string} ruc - The ruc to validate | |
* @returns {boolean} | |
*/ | |
isRUC: function(ruc) { | |
if (ruc.match(/[^0-9]+/g) === null && ruc.length == 11) { | |
var rucFirstTwo = ruc.substr(0, 2); | |
if (rucFirstTwo != "10" && rucFirstTwo != "15" && rucFirstTwo != "17" && rucFirstTwo != "20") return false; | |
var num; | |
var i; | |
var sum = 0; | |
var m = 5; | |
for (i = 0; i < 4; i++) { | |
num = ruc[i]; | |
sum += parseInt(num) * m; | |
m--; | |
} | |
m = 7; | |
for (i = 4; i < 10; i++) { | |
num = ruc[i]; | |
sum += parseInt(num) * m; | |
m--; | |
} | |
var intNum = parseInt(sum / 11); | |
var aux = 11 - (sum - intNum * 11); | |
var res = aux == 10 ? 0 : (aux == 11 ? 1 : aux); | |
return res == ruc[10]; | |
} | |
return false; | |
}, | |
/** | |
* Validate RFC (Mexico) | |
* @method module:Fizzmod.Utils#isRFC | |
* @access public | |
* @param {string} RFC - The RFC to validate | |
* @returns {boolean} | |
*/ | |
isRFC: function(RFC) { | |
return /[A-Z\{\¡\!\"\#\$\&\%\/\(\)\=]{3,4} ?([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|1[0-9]|2[0-9]|3[0-1]) ?[A-z0-9]{3}/i.test(RFC); | |
}, | |
/** | |
* Return an array with unique values | |
* @method module:Fizzmod.Utils#arrayUnique | |
* @access public | |
* @param {Array} arr - The array | |
* @returns {Array} | |
*/ | |
arrayUnique: function(arr) { | |
return arr.filter(function(value, index, self) { | |
return self.indexOf(value) === index; | |
}); | |
}, | |
/** | |
* Search through an object recursively and return the first match of the key:value passed | |
* @method module:Fizzmod.Utils#objectSearch | |
* @access public | |
* @param {Object} object - The haystack | |
* @param {Object} needle - Key value pair that will be searched | |
* @returns {Object} | |
* @example | |
*var data = [{ | |
* id: 0, | |
* name: 'key 0', | |
* children: [{ | |
* id: 1, | |
* name: 'key 1', | |
* children: [{ | |
* id: 2, | |
* name: 'key 2', | |
* item: [{ | |
* id: 3, | |
* name: 'key 3' | |
* }], | |
* item: [{ | |
* id: 4, | |
* name: 'key 4' | |
* }] | |
* }] | |
* }] | |
*}]; | |
*Fizzmod.Utils.objectSearch(data, {id: 4}); //{ id: 4, name: 'key 4'}; | |
*/ | |
objectSearch: function(object, needle) { | |
var p, key, val, tRet; | |
for (p in needle) { | |
if (needle.hasOwnProperty(p)) { | |
key = p; | |
val = needle[p]; | |
} | |
} | |
for (p in object) { | |
if (p == key) { | |
if (object[p] == val) { | |
return object; | |
} | |
} else if (object[p] instanceof Object) { | |
if (object.hasOwnProperty(p)) { | |
tRet = Utils.objectSearch(object[p], needle); | |
if (tRet) { | |
return tRet; | |
} | |
} | |
} | |
} | |
return false; | |
}, | |
/** | |
* Serialize an object into query string | |
* @method module:Fizzmod.Utils#serialize | |
* @access public | |
* @param {object} object - The object that will be converted into query string | |
* @param {boolean} addAmp - Whether to add ampersand at the beginning or not. | |
* @returns {string} A valid query string | |
*/ | |
serialize: function(object, addAmp) { | |
if (typeof object !== 'object') | |
return ""; | |
var str = []; | |
for (var p in object) { | |
if (object.hasOwnProperty(p)) { | |
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(object[p])); | |
} | |
} | |
return (addAmp ? "&" : "") + str.join("&"); | |
}, | |
/** | |
* Unserialize a query string into an object | |
* @method module:Fizzmod.Utils#unserialize | |
* @access public | |
* @param {string} string - The object that will be converted into query string | |
* @returns {object} | |
*/ | |
unserialize: function(string) { | |
var query = {}; | |
if (string.indexOf("?") === 0) | |
string = string.substr(1); | |
var parts = string.split('&'); | |
for (var i = 0; i < parts.length; i++) { | |
var part = parts[i].split('='); | |
query[decodeURIComponent(part[0])] = decodeURIComponent(part[1] || ''); | |
} | |
return query; | |
}, | |
/** | |
* Join array elements with glue string - PHP implode alike | |
* @method module:Fizzmod.Utils#implode | |
* @access public | |
* @param {object|array} pieces - The array|object to implode. If object it will implode the values, not the keys. | |
* @param {string} [glue=','] - The glue | |
* @returns {string} The imploded array|object | |
* @example Fizzmod.implode(['Foo', 'Bar']); //'Foo,Bar' | |
* | |
*/ | |
implode: function(pieces, glue) { | |
if (pieces instanceof Array) | |
return pieces.join(glue || ","); | |
else if (typeof pieces === 'object') { | |
var arr = []; | |
for (var o in pieces) { | |
arr.push(pieces[o]); | |
} | |
return arr.join(glue || ","); | |
} | |
return ""; | |
}, | |
/** | |
* Formats a number | |
* @method module:Fizzmod.Utils#formatPrice | |
* @param {number|string} number - The number to format | |
* @param {string} [thousands="."] - thousands delimiter | |
* @param {string} [decimals=","] - decimal delimiter | |
* @param {integer} [length=2] - length of decimal | |
* @param {boolean/string} [currency] - If true, the currency setted with Fizzmod.Utils.setCurrency("$") will be added, if a currency (string) is passed it will use that instead; | |
* @returns {string} The formatted price | |
*/ | |
formatPrice: function(number, thousands, decimals, length, currency) { | |
currency = this.currency ? this.currency : (typeof currency == "string" ? currency : ""); | |
length = typeof length !== 'number' ? 2 : length; | |
var re = '\\d(?=(\\d{' + (3) + '})+' + (length > 0 ? '\\D' : '$') + ')'; | |
number = (number * 1).toFixed(Math.max(0, ~~length)); | |
return currency + number.replace('.', (decimals || ",")).replace(new RegExp(re, 'g'), '$&' + (thousands || '.')); | |
}, | |
/** | |
* Sets the currency that will be used by helper functions | |
* @method module:Fizzmod.Utils#setCurrency | |
* @param {string} currency - The currency | |
*/ | |
setCurrency: function(currency) { | |
this.currency = currency; | |
}, | |
/** | |
* Formats a date (dd/mm/yyyy hh:mm:ss) | |
* @method module:Fizzmod.Utils#formatDate | |
* @param {object} date - Date object | |
* @returns {string} The formatted date | |
*/ | |
formatDate: function(date) { | |
if (typeof date == "object") { | |
var minutes = date.getMinutes(); | |
var hour = date.getHours(); | |
var day = date.getDate(); | |
var month = date.getMonth() + 1; | |
var year = date.getFullYear(); | |
var seconds = date.getSeconds(); | |
month = month > 9 ? month : "0" + month; | |
day = day > 9 ? day : "0" + day; | |
hour = hour > 9 ? hour : "0" + hour; | |
minutes = minutes > 9 ? minutes : "0" + minutes; | |
seconds = seconds > 9 ? seconds : "0" + seconds; | |
return day + "/" + month + "/" + year + " " + hour + ":" + minutes + ":" + seconds; | |
} | |
return null; | |
}, | |
/** | |
* Multiple string replace, PHP str_replace clone | |
* @method module:Fizzmod.Utils#strReplace | |
* @param {string|Array} search - The value being searched for, otherwise known as the needle. An array may be used to designate multiple needles. | |
* @param {string|Array} replace - The replacement value that replaces found search values. An array may be used to designate multiple replacements. | |
* @param {string} subject - The subject of the replacement | |
* @returns {string} The modified string | |
* @example Fizzmod.Utils.strReplace(["hola", "mundo"], ["hello", "world"], "hola mundo"); //Output "hello world" | |
*Fizzmod.Utils.strReplace(["uno", "dos"], "hola", "uno dos tres"); //Output "hola hola tres" | |
*/ | |
strReplace: function(search, replace, subject) { | |
var regex; | |
if (search instanceof Array) { | |
for (var i = 0; i < search.length; i++) { | |
search[i] = search[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); | |
regex = new RegExp(search[i], "g"); | |
subject = subject.replace(regex, (replace instanceof Array ? replace[i] : replace)); | |
} | |
} else { | |
search = search.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); | |
regex = new RegExp(search, "g"); | |
subject = subject.replace(regex, (replace instanceof Array ? replace[0] : replace)); | |
} | |
return subject; | |
}, | |
/** | |
* Removes the host from an URL | |
* @method module:Fizzmod.Utils#stripHost | |
* @param {string} URL - The URL | |
* @returns {string} The modified string | |
* @example Fizzmod.Utils.stripHost("http://test.vtexcommercestable.com.br/contacto/test"); // "/contacto/test" | |
*/ | |
stripHost: function(URL) { | |
return URL.toString().replace(/https?:\/\/.*?\//i, "/"); | |
}, | |
/** | |
* Removes the host from an URL | |
* @method module:Fizzmod.Utils#addHttp | |
* @param {string} URL - The URL | |
* @returns {string} The modified string | |
* @example Fizzmod.Utils.addHttp("google.com.ar"); // "http://google.com.ar" | |
*/ | |
addHttp: function(URL) { | |
if (!/^(?:f|ht)tps?:\/\//i.test(URL)) | |
URL = "http://" + URL; | |
return URL; | |
}, | |
/** | |
* Sanitize a string, removing/replacing all special characters and spaces with underscore | |
* @method module:Fizzmod.Utils#sanitizeString | |
* @param {string} str - The string to sanitize | |
* @param {string} [replace="-"] - The string to replace white spaces with, default "-" | |
* @returns {string} The modified string | |
* @example Fizzmod.Utils.sanitizeString("hóla múndo"); //Output "hola-mundo" | |
*/ | |
sanitizeString: function(str, replace) { | |
replace = typeof replace == "string" ? replace : "-"; | |
str = str.toLowerCase(); | |
str = str.replace(/[\[\]\(\)\-\{\}\^]/g, ""); | |
str = str.replace(/[àáâãäåª]/g, "a"); | |
str = str.replace(/[éèëê]/g, "e"); | |
str = str.replace(/[íìïî]/g, "i"); | |
str = str.replace(/[óòöô]/g, "o"); | |
str = str.replace(/[úùüû]/g, "u"); | |
str = str.replace(/[ñ]/g, "n"); | |
str = str.replace(/[ç]/g, "c"); | |
str = str.replace(/ /g, replace); | |
return str; | |
}, | |
/** | |
* Capitalize a string | |
* @method module:Fizzmod.Utils#capitalize | |
* @param {string} URL - The String | |
* @returns {string} The modified string | |
* @example Fizzmod.Utils.capitalize("foo bar"); // "Foo Bar" | |
*/ | |
capitalize: function(str) { | |
return str.replace(/(?:^|\s)\S/g, function(match) { | |
return match.toUpperCase(); | |
}); | |
}, | |
/** | |
* Get window height | |
* @method module:Fizzmod.Utils#getWindowHeight | |
* @returns {int} The modified string | |
*/ | |
getWindowHeight: function() { | |
return window.innerHeight ? window.innerHeight : $(window).height(); | |
}, | |
/** | |
* Get window width | |
* @method module:Fizzmod.Utils#getWindowWidth | |
* @returns {int} The modified string; | |
*/ | |
getWindowWidth: function() { | |
return $(window).width(); | |
}, | |
/** | |
* Get location origin | |
* @method module:Fizzmod.Utils#getLocationOrigin | |
* @returns {string} The location origin, ie: http://host.com | |
*/ | |
getLocationOrigin: function() { | |
if (!window.location.origin) | |
return window.location.protocol + "\/\/" + window.location.hostname + (window.location.port ? ':' + window.location.port : ''); | |
return window.location.origin; | |
}, | |
/** | |
* Check whether the browser is IE and return the version if so. | |
* @method module:Fizzmod.Utils#detectIE | |
* @returns {string} The IE version or false if other browser | |
*/ | |
detectIE: function() { | |
var ua = window.navigator.userAgent; | |
var msie = ua.indexOf('MSIE '); | |
if (msie > 0) { | |
// IE 10 or older => return version number | |
return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10); | |
} | |
var trident = ua.indexOf('Trident/'); | |
if (trident > 0) { | |
// IE 11 => return version number | |
var rv = ua.indexOf('rv:'); | |
return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10); | |
} | |
var edge = ua.indexOf('Edge/'); | |
if (edge > 0) { | |
// IE 12 => return version number | |
return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10); | |
} | |
// other browser | |
return false; | |
}, | |
/** | |
* Check whether a the device supports touch or not. | |
* @method module:Fizzmod.Utils#isTouchDevice | |
* @returns {boolean} | |
*/ | |
isTouchDevice: function() { | |
return supportsTouch; | |
}, | |
/** | |
* Return the length of an item (Object mostly) | |
* @method module:Fizzmod.Utils#length | |
* @param {mixed} | |
* @returns {int} | |
*/ | |
length: function(item) { | |
if (typeof item.length != "undefined") | |
return item.length; | |
if (typeof item == "object") | |
return Object.keys(item).length; | |
return 0; | |
}, | |
/** | |
* @method module:Fizzmod.Utils#delay | |
* @param {array} timeouts - An array of milliseconds on which the callbacks will be executed | |
* @param {...functions} callbacks | |
* @returns {int} | |
*/ | |
delay: function() { | |
var timeouts = Array.prototype.shift.call(arguments); | |
var callbacks = Array.prototype.slice.call(arguments); | |
var func = function() { | |
var callbacksLength = callbacks.length; | |
while (callbacksLength--) { | |
callbacks[callbacksLength].call(null); | |
} | |
}; | |
for (var i = 0, len = timeouts.length; i < len; i++) { | |
setTimeout(func, timeouts[i]); | |
} | |
}, | |
googleMapLoaded: function() { | |
return typeof google !== "undefined" && typeof google.maps !== "undefined"; | |
}, | |
/** | |
* @method module:Fizzmod.Utils#buildQueryString | |
* @param {mixed} name - The param name | |
* @param {mixed} value - The param value | |
* @param {string} [queryString] - The url/query string where the values will be added/removed | |
* @returns String The new url / query string | |
* @example Fizzmod.Utils.buildQueryString("param", "value") // Adds param=value to current query string | |
* Fizzmod.Utils.buildQueryString("param", undefined) // Removes param from current query string | |
* Fizzmod.Utils.buildQueryString(["param1", "param2"], ["value1", "value2"]) // Adds param1=value1 and param2=value2 to current query string | |
* Fizzmod.Utils.buildQueryString("param", "value", "?myParam=4&foo=bar") // Adds param=value to passed query string | |
* Fizzmod.Utils.buildQueryString("param", "value", "/foo/var") // Adds param=value to passed url | |
*/ | |
buildQueryString: function(name, value, url) { | |
url = url || location.search; | |
url = url.split("?"); | |
var path = url[0] || ""; | |
var queryString = url[1] || ""; | |
var _obj = {}; | |
var arr = queryString.split("&"); | |
if (arr[0] == "") arr.pop(); | |
// Parsea los valores de "queryString" | |
$.each(arr, function() { | |
var _tmp = this.split("="); | |
if (_tmp[0] == "fq") { | |
var parts = _tmp[1].split(":"); | |
if (typeof _obj["fq"] == "undefined") _obj["fq"] = {}; | |
_obj["fq"][parts[0]] = parts[1] || ""; | |
} else _obj[_tmp[0]] = _tmp[1] || ""; | |
}); | |
// Modifica los que se pasan por parámetro | |
if (typeof name == "object" && typeof value == "object") $.each(name, function(i, e) { | |
if (name[i] == "fq") { | |
var parts = value[i].split(":"); | |
if (typeof _obj[name[i]] == "undefined") _obj[name[i]] = {}; | |
_obj[name[i]][parts[0]] = parts[1] || undefined; | |
} | |
_obj[name[i]] = value[i] || undefined; | |
}); | |
else { | |
if (name == "fq") { | |
var parts = value.split(":"); | |
if (typeof _obj[name] == "undefined") _obj[name] = {}; | |
_obj[name][parts[0]] = parts[1] || undefined; | |
} else _obj[name] = value || undefined; | |
} | |
// Arma el query string con los valores modificados | |
var _p = "?"; | |
var first = true; | |
$.each(_obj, function(i, e) { | |
if (typeof e == "undefined") return; // Si el valor es undefined, se saca del query string | |
if (i == "fq") { | |
$.each(e, function(ii, ee) { | |
first ? first = !first : _p += "&"; | |
_p += i + "=" + ii + ":" + ee; | |
}); | |
} else { | |
first ? first = !first : _p += "&"; | |
_p += i + "=" + e; | |
} | |
}) | |
if (_p == "?") _p = ""; | |
return path + _p; | |
} | |
}; | |
Fizzmod.prototype.Utils = Utils; | |
var onceEventsCallbacksQueue = { | |
custom: {} | |
}; | |
var eventsCallbacksQueue = { | |
resize: [], | |
resizeStop: [], | |
hashChange: [], | |
custom: {} | |
}; | |
var addEvent = function(object, type, callback) { | |
if (object === null || typeof(object) == 'undefined') return; | |
if (object.addEventListener) { | |
object.addEventListener(type, callback, false); | |
} else if (object.attachEvent) { | |
object.attachEvent("on" + type, callback); | |
} else { | |
object["on" + type] = callback; | |
} | |
}; | |
var resizeStopTimeout; | |
addEvent(window, "resize", function(event) { | |
for (var i = 0, length = eventsCallbacksQueue.resize.length; i < length; i++) { | |
eventsCallbacksQueue.resize[i].call(null, event); | |
} | |
if (eventsCallbacksQueue.resizeStop.length) { | |
resizeStopTimeout = setTimeout(function() { | |
for (var i = 0, length = eventsCallbacksQueue.resizeStop.length; i < length; i++) { | |
eventsCallbacksQueue.resizeStop[i].call(null, event); | |
} | |
}, 100); | |
} | |
}); | |
addEvent(window, "hashchange", function(event) { | |
for (var i = 0, length = eventsCallbacksQueue.hashChange.length; i < length; i++) { | |
eventsCallbacksQueue.hashChange[i].call(null, event); | |
} | |
}); | |
/** | |
* Fizzmod Events | |
* @class module:Fizzmod.Events | |
* @author Marcos Casagrande | |
* @example | |
* Fizzmod.Events.resize(function(e){ | |
* console.log("Window resized!"); | |
* }) | |
* .resizeStop(function(e){ | |
* console.log("Window resize ended"); | |
* }); | |
*/ | |
var Events = { | |
/** | |
* Attach an event listener on a target | |
* This method accepts: | |
* - 3 parameters when attaching a event to a DOM element (target, event, callback) | |
* - 2 arguments when creating a custom event to be triggered later (event, callback) | |
* @method module:Fizzmod.Events#on | |
* @access public | |
* | |
* @example | |
* //attach event to DOM element | |
* Fizzmod.Events.on(window, "scroll", function(e){ console.log("Window has scrolled!") }); | |
* | |
* //Custom Event | |
* Fizzmod.Events.on("myEvent", function(param, paramN){ console.log("myEvent triggered") }); | |
* Fizzmod.Events.trigger("myEvent", param, paramN); | |
*/ | |
on: function() { | |
if (arguments.length > 2) | |
addEvent(arguments[0], arguments[1], arguments[2]); //target, event, callback | |
if (arguments.length == 2) { | |
var event = arguments[0]; | |
var callback = arguments[1]; | |
if (typeof event === "string" && typeof callback === "function") { | |
if (!(event in eventsCallbacksQueue.custom)) | |
eventsCallbacksQueue.custom[event] = []; | |
eventsCallbacksQueue.custom[event].push(callback); | |
} | |
} | |
return this; | |
}, | |
/** | |
* Register an event that will be triggered once | |
* | |
* @method module:Fizzmod.Events#once | |
* @access public | |
* @param {string} event - Event name | |
* @param {function} callback - The function callback | |
* | |
* Fizzmod.Events.once("myEvent", function(param, paramN){ console.log("myEvent triggered") }); | |
* Fizzmod.Events.trigger("myEvent", param, paramN); | |
*/ | |
once: function() { | |
if (arguments.length == 2) { | |
var event = arguments[0]; | |
var callback = arguments[1]; | |
if (typeof event === "string" && typeof callback === "function") { | |
if (!(event in onceEventsCallbacksQueue.custom)) | |
onceEventsCallbacksQueue.custom[event] = []; | |
onceEventsCallbacksQueue.custom[event].push(callback); | |
} | |
} | |
}, | |
/** | |
* Trigger a registered custom event | |
* @method module:Fizzmod.Events#trigger | |
* @param {string} - Event | |
* @example | |
*Fizzmod.Events.trigger("myEvent", params); | |
*/ | |
trigger: function(event) { | |
if (arguments.length < 1) | |
return; | |
var i; | |
var length; | |
Array.prototype.shift.call(arguments); | |
if (event in eventsCallbacksQueue.custom) { | |
for (i = 0, length = eventsCallbacksQueue.custom[event].length; i < length; i++) { | |
eventsCallbacksQueue.custom[event][i].apply(null, arguments); | |
} | |
} | |
if (event in onceEventsCallbacksQueue.custom) { | |
i = onceEventsCallbacksQueue.custom[event].length; | |
while (i--) { | |
onceEventsCallbacksQueue.custom[event][i].apply(null, arguments); | |
onceEventsCallbacksQueue.custom[event].splice(i, 1); | |
} | |
} | |
}, | |
/** | |
* Window resize event listener | |
* @method module:Fizzmod.Events#resize | |
* @param {function} callback - The callback that will be called upon window resize, event will be passed along. | |
* @return {object} Fizzmod.Events (chainable) | |
*/ | |
resize: function(callback) { | |
eventsCallbacksQueue.resize.push(callback); | |
return this; | |
}, | |
/** | |
* Window resize stop event listener | |
* @method module:Fizzmod.Events#resizeStop | |
* @param {function} callback - The callback that will be called upon window resize stop, event will be passed along. | |
* @return {object} Fizzmod.Events (chainable) | |
*/ | |
resizeStop: function(callback) { | |
eventsCallbacksQueue.resizeStop.push(callback); | |
return this; | |
}, | |
/** | |
* Window hashchange listener, The hashchange event fires when a window's hash changes (location.hash) | |
* @method module:Fizzmod.Events#hashChange | |
* @param {function} callback - The callback that will be called upon window hash change, event will be passed along. | |
* @return {object} Fizzmod.Events (chainable) | |
*/ | |
hashChange: function(callback) { | |
eventsCallbacksQueue.hashChange.push(callback); | |
return this; | |
} | |
}; | |
Fizzmod.prototype.Events = Events; | |
/** | |
* Fizzmod Checkout | |
* @class module:Fizzmod.Checkout | |
* @author Marcos Casagrande | |
* @example | |
*Fizzmod.Checkout.onCart(function(){ | |
* console.log("Checkout Cart!"); | |
*}) | |
*.onEmail(function(e){ | |
* console.log("Checkout Emails!"); | |
*}); | |
*/ | |
Fizzmod.prototype.Checkout = (function() { | |
var hashEvents = ["cart", "email", "profile", "shipping", "payment"]; | |
var GTMEvents = ["orderPlaced", "cartLoaded"]; //This events are called only once. | |
var eventType = { | |
ON: 1, | |
ONCE: 2 | |
}; | |
var checkoutEventsCallback = { | |
cart: [], | |
email: [], | |
profile: [], | |
shipping: [], | |
payment: [], | |
cartLoaded: [], | |
orderPlaced: [], | |
itemsUpdated: [] | |
}; | |
var checkoutOnceEventsCallback = { | |
cart: [], | |
email: [], | |
profile: [], | |
shipping: [], | |
payment: [], | |
cartLoaded: [], | |
orderPlaced: [], | |
itemsUpdated: [] | |
}; | |
function Checkout() {} | |
function setCheckoutStepClass(step) { | |
if (~hashEvents.indexOf(step)) { | |
var actualClass = step + "Step"; | |
var removeClasses = hashEvents.join("Step "); | |
removeClasses.replace(actualClass, ""); | |
$("body").removeClass(removeClasses).addClass(actualClass); | |
} | |
} | |
function eventCallback(event, type, extra, tagManager) { | |
var j; | |
setCheckoutStepClass(event); | |
if ((type & eventType.ON) && event in checkoutEventsCallback) { | |
j = checkoutEventsCallback[event].length; | |
while (j--) { | |
checkoutEventsCallback[event][j].call(null, event, extra); | |
} | |
} | |
if ((type & eventType.ONCE) && event in checkoutOnceEventsCallback) { | |
j = checkoutOnceEventsCallback[event].length; | |
while (j--) { | |
checkoutOnceEventsCallback[event][j].call(null, event, extra); | |
checkoutOnceEventsCallback[event].splice(j, 1); | |
} | |
} | |
return; | |
} | |
setCheckoutStepClass(window.location.hash.replace(/[^A-Z]/gi, "")); | |
Checkout.prototype = { | |
/** | |
* Listen to the given checkout event only once, the event will only fire ONCE. | |
* @method module:Fizzmod.Checkout#once | |
* @access public | |
* @param {string} events - The events to listen to | |
* @param {...function} callback - The callback that will be called upon entering the given event. | |
* @returns {object} Fizzmod.Checkout (chainable) | |
* @example | |
*Fizzmod.Checkout.once("cart", function(){ | |
* vtexjs.checkout.orderForm().done(function(){ | |
* | |
* }); | |
*}); | |
*/ | |
once: function() { | |
var events = Array.prototype.shift.call(arguments).split(" "); | |
var callbacks = Array.prototype.slice.call(arguments); | |
var location = window.location.hash.toLowerCase(); | |
for (var i = 0, len = events.length; i < len; i++) { | |
if (~GTMEvents.indexOf(events[i])) { | |
TagManager.once.apply(null, [events[i]].concat(Array.prototype.slice.call(arguments))); | |
} else { | |
if (~location.indexOf(events[i])) { | |
setCheckoutStepClass(events[i]); | |
for (var j = 0, callbacksLength = callbacks.length; j < callbacksLength; j++) { | |
callbacks[j].call(null, events[i]); | |
} | |
} else if (events[i] in checkoutOnceEventsCallback) { | |
checkoutOnceEventsCallback[events[i]] = checkoutOnceEventsCallback[events[i]].concat(callbacks); | |
} | |
} | |
} | |
return this; | |
}, | |
/** | |
* Listen to the given checkout event | |
* @method module:Fizzmod.Checkout#on | |
* @param {string} events - The events to listen to | |
* @param {...function} callbacks - The callback that will be called upon entering the given event. | |
* @returns {object} Fizzmod.Checkout (chainable) | |
* @example | |
*Fizzmod.Checkout.on("cart payment", function(){ | |
* //some function | |
*}, | |
*function(){ | |
* //other function | |
*}) | |
*/ | |
on: function() { | |
var events = Array.prototype.shift.call(arguments).split(" "); | |
var callbacks = Array.prototype.slice.call(arguments); | |
var location = window.location.hash.toLowerCase(); | |
for (var i = 0, len = events.length; i < len; i++) { | |
if (events[i] in checkoutEventsCallback) { | |
if (~GTMEvents.indexOf(events[i])) { | |
TagManager.on.apply(null, [events[i]].concat(Array.prototype.slice.call(arguments))); | |
} else { | |
checkoutEventsCallback[events[i]] = checkoutEventsCallback[events[i]].concat(callbacks); | |
//Hash events | |
if (~location.indexOf(events[i])) { | |
setCheckoutStepClass(events[i]); | |
var j = callbacks.length; | |
while (j--) { | |
callbacks[j].call(null, events[i]); | |
} | |
} | |
} | |
} | |
} | |
return this; | |
}, | |
/** | |
* Checkout view listener. | |
* @method module:Fizzmod.Checkout#onOrderPlaced | |
* @param {...function} callbacks - The callback that will be called upon entering the checkout. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onCheckout: function() { | |
if (window.location.href.match(/\/checkout/)) { | |
var callbacks = Array.prototype.slice.call(arguments); | |
var i = callbacks.length; | |
while (i--) { | |
callbacks[i].call(null, "checkout"); | |
} | |
} | |
return this; | |
}, | |
/** | |
* Checkout Order Placed page view. | |
* @method module:Fizzmod.Checkout#onOrderPlacedView | |
* @param {...function} callbacks - The callback that will be called upon entering order placed. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onOrderPlacedView: function() { | |
if (window.location.href.match(/\/checkout\/orderPlaced/)) { | |
var callbacks = Array.prototype.slice.call(arguments); | |
var i = callbacks.length; | |
while (i--) { | |
callbacks[i].call(null, "orderPlacedView"); | |
} | |
} | |
return this; | |
}, | |
/** | |
* Checkout Order Placed event listener. | |
* @method module:Fizzmod.Checkout#onOrderPlaced | |
* @param {...function} callbacks - The callback that will be called upon orderPlaced event. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onOrderPlaced: function() { | |
return this.on.apply(null, ["orderPlaced"].concat(Array.prototype.slice.call(arguments))); | |
}, | |
/** | |
* Checkout cart view listener, The onCart event fires when the VTEX checkout step is cart. | |
* @method module:Fizzmod.Checkout#onCart | |
* @param {...function} callbacks - The callback that will be called upon entering the cart view. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onCart: function(callback) { | |
return this.on.apply(null, ["cart"].concat(Array.prototype.slice.call(arguments))); | |
}, | |
/** | |
* Checkout email view listener, The onEmail event fires when the VTEX checkout step is email. | |
* @method module:Fizzmod.Checkout#onEmail | |
* @param {...function} callbacks - The callback that will be called upon entering the email view. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onEmail: function(callback) { | |
return this.on.apply(null, ["email"].concat(Array.prototype.slice.call(arguments))); | |
}, | |
/** | |
* Checkout profile view listener, The onProfile event fires when the VTEX checkout step is profile. | |
* @method module:Fizzmod.Checkout#onProfile | |
* @param {...function} callbacks - The callback that will be called upon entering the email view. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onProfile: function(callback) { | |
return this.on.apply(null, ["profile"].concat(Array.prototype.slice.call(arguments))); | |
}, | |
/** | |
* Checkout shipping view listener, The onShipping event fires when the VTEX checkout step is shipping. | |
* @method module:Fizzmod.Checkout#onShipping | |
* @param {...function} callbacks - The callback that will be called upon entering the email view. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onShipping: function(callback) { | |
return this.on.apply(null, ["shipping"].concat(Array.prototype.slice.call(arguments))); | |
}, | |
/** | |
* Checkout payment view listener, The onPayment event fires when the VTEX checkout step is shipping. | |
* @method module:Fizzmod.Checkout#onPayment | |
* @param {...function} callbacks - The callback that will be called upon entering the email view. | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onPayment: function(callback) { | |
return this.on.apply(null, ["payment"].concat(Array.prototype.slice.call(arguments))); | |
}, | |
/** | |
* Checkout cartLoaded event listener, The onCartLoaded event fires when the VTEX orderForm is loaded for the first time. | |
* @method module:Fizzmod.Checkout#onCartLoaded | |
* @param {...function} callbacks - The callback that will be called on cart loaded | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onCartLoaded: function(callback) { | |
return this.on.apply(null, ["cartLoaded"].concat(Array.prototype.slice.call(arguments))); | |
}, | |
/** | |
* Checkout itemsUpdated event listener, The onItemsUpdated event fires whenever an item is modified | |
* @method module:Fizzmod.Checkout#onItemsUpdated | |
* @param {...function} callbacks - The callback that will be called on itemsUpdated | |
* @return {object} Fizzmod.Checkout (chainable) | |
*/ | |
onItemsUpdated: function(callback) { | |
return this.on.apply(null, ["itemsUpdated"].concat(Array.prototype.slice.call(arguments))); | |
} | |
}; | |
Events.hashChange(function() { | |
var location = window.location.hash.toLowerCase(); | |
console.log("HashChange: " + location); | |
var hashes = ["cart", "email", "profile", "shipping", "payment"]; | |
for (var i = 0, hashesLen = hashes.length; i < hashesLen; i++) { | |
var event = hashes[i]; | |
if (~location.indexOf(event)) { | |
eventCallback(event, eventType.ON | eventType.ONCE); | |
} | |
} | |
}); | |
/** Detect items Update **/ | |
$(document).ajaxSuccess(function(event, xhr, settings) { | |
try { | |
if (settings.url.match(vtexjs.checkout._getUpdateItemURL()) && typeof xhr.responseText != "undefined") { | |
var orderForm = $.parseJSON(xhr.responseText); | |
eventCallback("itemsUpdated", eventType.ON | eventType.ONCE, orderForm); | |
} | |
} catch (e) {} | |
}); | |
return new Checkout(); | |
})(window); | |
//http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=processJSON&tags=monkey&tagmode=any&format=json | |
//TODO | |
var JSONP = (function() { | |
var unique = 0; | |
return function(url, callback, callbackName) { | |
// INIT | |
return $.Deferred(function() { | |
var def = this; | |
var callbackName = callbackName || "callback"; | |
var name = "_jsonp_" + unique++; | |
if (url.match(/\?/)) url += "&" + callbackName + "=" + name; | |
else url += "?" + callbackName + "=" + name; | |
// Create script | |
var script = document.createElement('script'); | |
script.type = 'text/javascript'; | |
script.src = url; | |
// Setup handler | |
window[name] = function(data) { | |
callback.call(window, data); | |
def.resolve(data); | |
document.getElementsByTagName('head')[0].removeChild(script); | |
script = null; | |
delete window[name]; | |
}; | |
// Load JSON | |
document.getElementsByTagName('head')[0].appendChild(script); | |
}).promise(); | |
}; | |
})(); | |
Fizzmod.prototype.JSONP = JSONP; | |
/** | |
* Fizzmod Ajax | |
* @class module:Fizzmod.Ajax | |
* @author Marcos Casagrande | |
* @example | |
* | |
*Fizzmod.Ajax.get('http://example.com', { foo: 'bar' }, function(result){ }, 'json'); | |
* | |
* //LOWERCASE! | |
*Fizzmod.ajax({ | |
* url: "http://example.com", | |
* type: 'POST', //'GET', 'PATCH', 'POST', 'PUT', 'DELETE' | |
* data: { foo: 1, bar: "text" }, | |
* headers: { "Content-type": "application/x-www-form-urlencoded" }, | |
* beforeSend: function(xhr){ | |
* //Before send operations | |
* | |
* }, | |
* success: function(result){ | |
* | |
* //Ajax success callback | |
* | |
* }, | |
* error: function(xhr){ | |
* | |
* //Ajax error callback | |
* | |
* } | |
*}).done(function(result){ | |
* | |
*}).fail(function(xhr){ | |
* | |
*}); | |
* | |
*/ | |
var Ajax = (function(window, undefined) { | |
function Ajax() { | |
var that = this; | |
var _priv = { | |
parseResult: function(result, type) { | |
if (type !== null && type.toUpperCase() == 'JSON') | |
return Utils.isJSON(result) ? JSON.parse(result) : result; | |
return result; | |
} | |
}; | |
this.methods = { | |
GET: 'GET', | |
PATCH: 'PATCH', | |
POST: 'POST', | |
PUT: 'PUT', | |
DELETE: 'DELETE' | |
}; | |
/** Privileged Methods **/ | |
/** | |
* Perform an asynchronous HTTP (Ajax) request | |
* @method module:Fizzmod.Ajax#_call | |
* @access private | |
* @param {string} [method='GET] - The HTTP method to use for the request | |
* @param {string} URL - A string containing the URL to which the request is sent. | |
* @param {object} settings - A set of key/value pairs that configure the Ajax request. All settings are optional. | |
*/ | |
this._call = function(method, URL, settings) { | |
settings = settings || {}; | |
return $.Deferred(function() { | |
var def = this; | |
var xhr; | |
if (!settings.crossDomain || !window.XDomainRequest) { | |
xhr = new XMLHttpRequest(); | |
} else if (window.XDomainRequest) { | |
xhr = new XDomainRequest(); | |
} | |
if (!xhr) | |
throw "XMLHttpRequest not supported"; | |
var requestMethod = typeof method == "string" ? method.toUpperCase() : that.methods.GET; | |
var queryString = settings.data ? Utils.serialize(settings.data) : ""; | |
if (typeof settings.dataType == "string" && settings.dataType.toUpperCase() == 'JSONP') { | |
return JSONP(URL, settings.jsonp); //TODO | |
} | |
xhr.open(requestMethod, URL + (requestMethod == that.methods.GET ? "?" + queryString : "")); | |
switch (requestMethod) { | |
case that.methods.POST: | |
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); | |
break; | |
} | |
if (typeof settings.headers == "object") { | |
for (var header in settings.headers) { | |
xhr.setRequestHeader(header, settings.headers[header]); | |
} | |
} | |
xhr.onload = function() { | |
if (xhr.status == 200 || window.XDomainRequest) { //IE returns no status for 304 | |
var response = _priv.parseResult(xhr.responseText, settings.dataType || null); | |
if (settings.success !== undefined) | |
settings.success.call(null, response); | |
def.resolve(response); | |
} else { | |
if (settings.error !== undefined) | |
settings.error.call(null, xhr); | |
def.reject(xhr); | |
} | |
}; | |
xhr.onerror = function() { | |
if (settings.error !== undefined) | |
settings.error.call(null, xhr); | |
def.reject(xhr); | |
}; | |
if (typeof settings.beforeSend == "function") { | |
settings.beforeSend.call(null, xhr); | |
} | |
xhr.send(queryString); | |
}).promise(); | |
}; | |
} | |
Ajax.prototype = { | |
/** | |
* Perform an asynchronous HTTP GET request | |
* @method module:Fizzmod.Ajax#get | |
* @param {string} URL - A string containing the URL to which the request is sent. | |
* @param {object|string} data - Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests | |
* @param {function} success - The success callback function | |
* @param {string} dataType - The request data Type. e.g: 'json' | |
* @returns {promise} | |
*/ | |
get: function(URL, data, success, dataType) { | |
var settings = { | |
data: data, | |
success: success, | |
dataType: dataType | |
}; | |
return this._call(this.methods.GET, URL, settings); | |
}, | |
/** | |
* Perform an asynchronous HTTP POST request | |
* @method module:Fizzmod.Ajax#post | |
* @param {string} URL - A string containing the URL to which the request is sent. | |
* @param {object|string} data - Data to be sent to the server. It is converted to a query string, if not already a string. | |
* @param {function} success - The success callback function | |
* @param {string} dataType - The request data Type. e.g: 'json' | |
* @returns {promise} | |
*/ | |
post: function(URL, data, success, dataType) { | |
var settings = { | |
data: data, | |
success: success, | |
dataType: dataType | |
}; | |
return this._call(this.methods.POST, URL, settings); | |
} | |
}; | |
return new Ajax(); | |
})(window); | |
/** | |
* Performs an asyncronous HTTP (Ajax) request. | |
* @method module:Fizzmod#ajax | |
* @param {object} options - A set of key/value pairs that configure the Ajax request. All settings are optional A default can be set for any option with Fizzmod.Ajax.setup() | |
* @example | |
*Fizzmod.ajax({ | |
* url: "http://example.com", | |
* type: 'POST', //'GET', 'PATCH', 'POST', 'PUT', 'DELETE' | |
* data: { foo: 1, bar: "text" }, | |
* headers: { "Content-type": "application/x-www-form-urlencoded" }, | |
* beforeSend: function(xhr){ | |
* //Before send operations | |
* | |
* }, | |
* success: function(result){ | |
* | |
* //Ajax success callback | |
* | |
* }, | |
* error: function(xhr){ | |
* | |
* //Ajax error callback | |
* | |
* } | |
*}).done(function(result){ | |
* | |
*}).fail(function(xhr){ | |
* | |
*}); | |
* | |
*/ | |
Fizzmod.prototype.ajax = function(options) { | |
return Ajax._call(options.type, options.url, options); | |
}; | |
Fizzmod.prototype.Ajax = Ajax; | |
/** | |
* Fizzmod Master Data class <br/> | |
* <b>NOTE:</b> You shouldn't call any underscore methods | |
* @class module:Fizzmod.MasterData | |
* @author Marcos Casagrande | |
* @example | |
*Fizzmod.MasterData.setStore("fravega"); //Mandatory - Set the current Store | |
* | |
* //[Optional] Set Entity - Default: 'CL' | |
*Fizzmod.MasterData.setEntity('CL'); | |
* | |
*Fizzmod.MasterData.newsletter("[email protected]").done(function(result) { | |
* if(result.isUpdate()){ | |
* console.log("User updated!"); | |
* }else if(result.isInsert()){ | |
* console.log("New user!"); | |
* } | |
*}); | |
*/ | |
Fizzmod.prototype.MasterData = (function($, window, undefined) { | |
function MasterData() { | |
var that = this; | |
/** | |
* @var {string} | |
* @description The current storeName, MUST BE EDITED and must be the a valid store name | |
* @example var storeName = "fravega"; | |
*/ | |
var storeName = null; | |
/** @constant {string} */ | |
var API_URL = "\/\/api.vtexcrm.com.br/{storeName}/dataentities/{entity}/{type}/"; | |
var API_ATTACHMENT_URL = "\/\/api.vtexcrm.com.br/{storeName}/dataentities/{entity}/documents/{id}/{field}/attachments"; | |
/** | |
* @var {string} | |
* @description Default entity that will be used if nothing is specified in every method | |
* @example var defaultEntity = "CL"; | |
*/ | |
var defaultEntity = "CL"; | |
/** @constant {string} */ | |
this.OP_INSERT = 'insert'; | |
/** @constant {string} */ | |
this.OP_UPDATE = 'update'; | |
/** | |
* | |
* | |
*/ | |
this.ERR_INVALID_USER = "User doesn't exist"; | |
this.ERR_INVALID_PARTNER = "Partner doesn't exist"; | |
this.ERR_INVALID_EMAIL = "Invalid email"; | |
/** Private Methods */ | |
var priv = { | |
types: { | |
DOCUMENTS: 'documents', | |
SEARCH: 'search', | |
SCHEMAS: 'schemas', | |
FACET: 'search/facet', | |
ATTACHMENT: 'documents' | |
}, | |
_getURL: function(entity, type, id) { | |
entity = entity !== undefined ? entity : defaultEntity; | |
if (storeName === null) | |
throw "storeName is not set, Fizzmod.MasterData.setStore(storeName) must be called"; | |
return Utils.strReplace(["{storeName}", "{entity}", "{type}"], [storeName, entity, type], API_URL) + (id !== undefined && id !== null ? id : ""); | |
}, | |
_getAttachmentURL: function(entity, id, field) { | |
entity = entity !== undefined ? entity : defaultEntity; | |
if (storeName === null) | |
throw "storeName is not set, Fizzmod.MasterData.setStore(storeName) must be called"; | |
return Utils.strReplace(["{storeName}", "{entity}", "{field}"], [storeName, entity, field], API_ATTACHMENT_URL) + (id !== undefined && id !== null ? id : ""); | |
}, | |
_call: function(method, id, data, entity, type, headers) { | |
return $.ajax({ | |
url: this._getURL(entity, type, id), | |
type: method, | |
accept: "application/vnd.vtex.ds.v10+json", | |
contentType: "application/json; charset=utf-8", | |
beforeSend: function(request) { | |
for (var header in headers) | |
request.setRequestHeader(header, headers[header]); | |
}, | |
crossDomain: true, | |
data: method !== "GET" && data !== null ? JSON.stringify(data) : data | |
}); | |
}, | |
_upload: function(id, data, entity, field) { | |
return $.ajax({ | |
url: this._getAttachmentURL(entity, id, field), | |
type: 'POST', | |
data: data, | |
processData: false, | |
contentType: false, | |
accept: "application/vnd.vtex.ds.v10+json", | |
enctype: 'multipart/form-data' | |
}); | |
} | |
}; | |
/** | |
* Fizzmod Success <br /><br /> | |
* <b>NOTE:</b> this class can only be accessed through a Fizzmod.MasterData success result | |
* @class module:Fizzmod.MasterData.FizzmodSuccess | |
* @access public | |
* @example | |
*Fizzmod.MasterData.newsletter("[email protected]").done(function(response) { | |
* //Get the response results, whatever it might be [array, object, string, integer] | |
* var results = response.getResults(); | |
* if(response.isUpdate()){ | |
* console.log("User updated!"); | |
* }else if(response.isInsert()){ | |
* console.log("New user!"); | |
* } | |
*}); | |
* | |
*/ | |
var FizzmodSuccess = function(result, operation) { | |
var _result = result; | |
var _operation = operation; | |
/** | |
* To check if the response was successfull or not. Used in "always" callback, | |
* @method module:Fizzmod.MasterData.FizzmodError#isOK | |
* @access public | |
* @returns {mixed} | |
*/ | |
this.isOK = function() { | |
return true; | |
}; | |
/** | |
* Check if the operation was an insert | |
* @method module:Fizzmod.MasterData.FizzmodSuccess#isInsert | |
* @access public | |
* @returns {boolean} Whether the operation was an insert or not | |
*/ | |
this.isInsert = function() { | |
return _operation == that.OP_INSERT; | |
}; | |
/** | |
* Check if the operation was an update | |
* @method module:Fizzmod.MasterData.FizzmodSuccess#isUpdate | |
* @access public | |
* @returns {boolean} Whether the operation was an update or not | |
*/ | |
this.isUpdate = function() { | |
return _operation == that.OP_UPDATE; | |
}; | |
/** | |
* Returns the results of the operation | |
* @method module:Fizzmod.MasterData.FizzmodSuccess#getResults | |
* @access public | |
* @returns {mixed} | |
*/ | |
this.getResults = function() { | |
return _result; | |
}; | |
}; | |
/** | |
* Fizzmod Error <br /><br /> | |
* <b>NOTE:</b> this class can only be accessed through a Fizzmod.MasterData error result | |
* @class module:Fizzmod.MasterData.FizzmodError | |
* @access public | |
* @example | |
*Fizzmod.MasterData.getUser("[email protected]", ["isNewsletterOptIn"]).done(function(response) { | |
* //success | |
*}).fail(function(error){ | |
* //error | |
* console.log(error.getResponse()); | |
* console.log(error.getMessage()); | |
*}); | |
* | |
*/ | |
var FizzmodError = function(error) { | |
var _response = null; | |
var _message = null; | |
if (typeof error == 'object') { | |
for (var key in error) { | |
if (error.hasOwnProperty(key) && typeof error[key] !== "function") { | |
if (key == "responseText") | |
_response = $.parseJSON(error[key]); | |
if (typeof key == 'string' && key.toLowerCase() == "message") | |
_message = error[key]; | |
else this[key] = error[key]; | |
} | |
} | |
} else if (typeof error == 'string') { | |
_message = error; | |
} | |
/** | |
* To check if the response was successfull or not. Used in "always" callback, | |
* @method module:Fizzmod.MasterData.FizzmodError#isOK | |
* @access public | |
* @returns {mixed} | |
*/ | |
this.isOK = function() { | |
return false; | |
}; | |
/** | |
* Returns the AJAX error response | |
* @method module:Fizzmod.MasterData.FizzmodError#getResponse | |
* @access public | |
* @returns {mixed} | |
*/ | |
this.getResponse = function() { | |
return _response; | |
}; | |
/** | |
* Returns the error message | |
* @method module:Fizzmod.MasterData.FizzmodError#getMessage | |
* @access public | |
* @returns {mixed} | |
*/ | |
this.getMessage = function() { | |
return _message !== null ? _message : (_response !== null && _response.Message !== undefined ? _response.Message : null); | |
}; | |
}; | |
/** Privileged methods */ | |
/** | |
* Check if a result is valid | |
* @method module:Fizzmod.MasterData#_resultOK | |
* @access private | |
* @param {object} result - The result that will be parsed | |
* @returns {boolean} | |
*/ | |
this._resultOK = function(result) { | |
return result !== undefined && result.length && result[0].id !== undefined; | |
}; | |
/** | |
* Parse a result | |
* @method module:Fizzmod.MasterData#_parseResult | |
* @access private | |
* @param {object} result - The result that will be parsed | |
* @returns {FizzmodSuccess} FizzmodSuccess object | |
*/ | |
this._parseResult = function(result, operation) { | |
return new FizzmodSuccess(result, operation); | |
}; | |
/** | |
* Parse an error | |
* @method module:Fizzmod.MasterData#_parseError | |
* @access private | |
* @param {object} error - The error that will be parsed | |
* @returns {FizzmodError} FizzmodError object | |
*/ | |
this._parseError = function(error) { | |
return new FizzmodError(error); | |
}; | |
/** | |
* Get a master data document | |
* @method module:Fizzmod.MasterData#_get | |
* @access private | |
* @param {string} id - The ID of the document to get | |
* @param {Array} [fields=["email", "id"]] - A list of fields to retrieve | |
* @param {string} entity - The entity of the document to get | |
* @returns {promise} | |
*/ | |
this._get = function(id, fields, entity) { | |
var defaults = ["email", "id"]; | |
fields = fields instanceof Array ? Utils.arrayUnique(fields.concat(["id"])) : defaults; | |
var data = { | |
"_fields": fields.join(",") | |
}; | |
return priv._call("GET", id, data, entity, priv.types.DOCUMENTS); | |
}; | |
/** | |
* Check if a master data document exists | |
* @method module:Fizzmod.MasterData#_exists | |
* @access private | |
* @param {string} id - The ID of the document to check | |
* @param {string} entity - The entity of the document to check | |
* @returns {promise} A rejected promise if it doesn't exist and a resolved one if it does | |
*/ | |
this._exists = function(id, entity) { | |
return $.Deferred(function() { | |
var def = this; | |
return priv._call("GET", id, { | |
_fields: "id" | |
}, entity, priv.types.DOCUMENTS).done(function(result) { | |
if (result !== undefined && result.id !== undefined) { | |
def.resolve(result); | |
} else def.reject(false); | |
}).fail(function(error) { | |
def.reject(error); | |
}); | |
}).promise(); | |
}; | |
/** | |
* Insert a document | |
* @method module:Fizzmod.MasterData#_insert | |
* @access private | |
* @param {Object} data - The data that will be inserted | |
* @param {string} entity - The entity of the document to insert | |
* @returns {promise} | |
*/ | |
this._insert = function(data, entity) { | |
return $.Deferred(function() { | |
var def = this; | |
return priv._call("POST", null, data, entity, priv.types.DOCUMENTS).done(function(result) { | |
def.resolve($.extend(data, result)); | |
}).fail(function(error) { | |
def.reject(error); | |
}); | |
}).promise(); | |
}; | |
/** | |
* Insert a document | |
* @method module:Fizzmod.MasterData#_insert | |
* @access private | |
* @param {Object} data - The data that will be inserted | |
* @param {string} entity - The entity of the document to insert | |
* @returns {promise} | |
*/ | |
this._upload = function(data, entity) { | |
return $.Deferred(function() { | |
var def = this; | |
return priv._call("POST", null, data, entity, priv.types.DOCUMENTS).done(function(result) { | |
def.resolve($.extend(data, result)); | |
}).fail(function(error) { | |
def.reject(error); | |
}); | |
}).promise(); | |
}; | |
/** | |
* Full update of a document, all fields must be specified in the request | |
* @method module:Fizzmod.MasterData#_fullUpdate | |
* @access private | |
* @param {string} id - The ID of the document to get | |
* @param {Object} data - The data that will be inserted | |
* @param {string} entity - The entity of the document to insert | |
* @returns {promise} | |
*/ | |
this._fullUpdate = function(id, data, entity) { | |
return priv._call("PUT", id, data, entity, priv.types.DOCUMENTS); | |
}; | |
/** | |
* Partial update of a document | |
* @method module:Fizzmod.MasterData#_partialUpdate | |
* @access private | |
* @param {string} id - The ID of the document to update | |
* @param {Object} data - The data that will be updated | |
* @param {string} entity - The entity of the document to insert | |
* @returns {promise} | |
*/ | |
this._partialUpdate = function(id, data, entity) { | |
return $.Deferred(function() { | |
var def = this; | |
return priv._call("PATCH", id, data, entity, priv.types.DOCUMENTS).done(function(result) { | |
def.resolve(data); | |
}).fail(function(error) { | |
def.reject(error); | |
}); | |
}).promise(); | |
}; | |
/** | |
* Performs a search | |
* @method module:Fizzmod.MasterData#_search | |
* @access private | |
* @param {Object} params - The search parameters | |
* @param {Array} fields - The fields that will be retrieved | |
* @param {string} entity - The entity where the search will be performed | |
* @param {int} [limit=49] - The search limit | |
* @param {int} [offset=0] - The search offset | |
* @returns {promise} | |
*/ | |
this._search = function(params, fields, entity, limit, offset) { | |
limit = limit || 49; | |
offset = offset || 0; | |
var headers = { | |
"REST-Range": "resources=" + offset + "-" + (limit + offset) | |
}; | |
params._fields = fields.join(","); | |
return priv._call("GET", null, params, entity, priv.types.SEARCH, headers); | |
}; | |
/** | |
* Performs a search by email | |
* @method module:Fizzmod.MasterData#_getByEmail | |
* @access private | |
* @param {string} email - The email that will be searched | |
* @param {string} entity - The entity where the search will be performed | |
* @returns {promise} | |
*/ | |
this._getByEmail = function(email, entity) { | |
return this._search({ | |
email: email | |
}, ["email", "id"], entity, 1, 0); | |
}; | |
/** | |
* Set the current Store | |
* @method module:Fizzmod.MasterData#setStore | |
* @param {string} store - The current store | |
* @returns {object} - The current instance (chainable) | |
*/ | |
this.setStore = function(store) { | |
storeName = store; | |
return this; | |
}; | |
/** | |
* Set the default entity | |
* @method module:Fizzmod.MasterData#setEntity | |
* @param {string} entity - The entity to set to default one | |
* @returns {object} - The current instance (chainable) | |
*/ | |
this.setEntity = function(entity) { | |
defaultEntity = entity; | |
return this; | |
}; | |
} | |
/** Public Methods */ | |
MasterData.prototype = { | |
/** | |
* Newsletter opt-in / opt-out | |
* @method module:Fizzmod.MasterData#newsletter | |
* @access public | |
* @param {string} email - The email of the user to opt-in/out | |
* @param {boolean} [newsletter=true] - Whether to opt-in/out | |
* @param {string} [entity='CL'] - The Entity | |
* @returns {promise} | |
* @example | |
*Fizzmod.MasterData.newsletter("[email protected]").done(function(response) { | |
* if(response.success){ //FizzmodSuccess | |
* console.log("Subscribed"); | |
* } | |
*}).fail(function(error){ console.log(error); }); //FizzmodError | |
*/ | |
newsletter: function(email, newsletter, entity) { | |
var that = this; | |
var data = { | |
isNewsletterOptIn: newsletter === undefined ? true : newsletter | |
}; | |
return $.Deferred(function() { | |
var def = this; | |
if (!Utils.isEmail(email)) | |
return def.reject(that._parseError(that.ERR_INVALID_EMAIL)); | |
that._getByEmail(email, entity).done(function(result) { | |
if (that._resultOK(result)) { | |
return that._partialUpdate(result[0].id, data, entity).done(function(result) { | |
def.resolve(that._parseResult(result, that.OP_UPDATE)); | |
}).fail(function(error) { | |
def.reject(that._parseResult(error)); | |
}); | |
} else { | |
return that._insert($.extend({ | |
email: email | |
}, data), entity).done(function(result) { | |
def.resolve(that._parseResult(result, that.OP_INSERT)); | |
}).fail(function(error) { | |
def.reject(that._parseResult(error)); | |
}); | |
} | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Get User by mail | |
* @method module:Fizzmod.MasterData#getUser | |
* @access public | |
* @param {string} email - The email of the user | |
* @param {Array} [fields] - A list of fields to retrieve | |
* @param {string} [entity='CL'] - The Entity of the user | |
* @returns {promise} | |
* @example | |
*Fizzmod.MasterData.getUser("[email protected]", ["isNewsletterOptIn"]).done(function(response) { | |
* if(response.result.isNewsletterOptIn){ //FizzmodSuccess | |
* console.log("Subscribed"); | |
* } | |
*}).fail(function(error){ console.log(error); }); //FizzmodError | |
*/ | |
getUser: function(email, fields, entity) { | |
var that = this; | |
return $.Deferred(function() { | |
var def = this; | |
if (!Utils.isEmail(email)) | |
return def.reject(that._parseError(that.ERR_INVALID_EMAIL)); | |
that._getByEmail(email, entity).done(function(result) { | |
if (that._resultOK(result)) { | |
return that._get(result[0].id, fields, entity).done(function(result) { | |
def.resolve(that._parseResult(result)); | |
}).fail(function(error) { | |
def.reject(that._parseResult(error)); | |
}); | |
} else def.reject(that._parseError(that.ERR_INVALID_USER)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Update User by email | |
* @method module:Fizzmod.MasterData#updateUser | |
* @access public | |
* @param {string} email - The email of the user | |
* @param {Object} data - The data that will be updated. | |
* @param {string} [entity='CL'] - The Entity | |
* @returns {promise} | |
* @example | |
*Fizzmod.MasterData.updateUser("[email protected]", | |
* {isNewsletterOptIn: true, firstName: 'Master', lastName: 'of the Matrix'}).done(function(response) { | |
* if(response.result.isNewsletterOptIn){ //FizzmodSuccess | |
* console.log("Subscribed"); | |
* } | |
*}).fail(function(error){ console.log(error); }); //FizzmodError | |
*/ | |
updateUser: function(email, data, entity) { | |
var that = this; | |
return $.Deferred(function() { | |
var def = this; | |
if (!Utils.isEmail(email)) | |
return def.reject(that._parseError(that.ERR_INVALID_EMAIL)); | |
return that._getByEmail(email, entity).done(function(result) { | |
if (that._resultOK(result)) { | |
return that._partialUpdate(result[0].id, data, entity).done(function(result) { | |
def.resolve(that._parseResult(result)); | |
}).fail(function(error) { | |
def.reject(error); | |
}); | |
} else def.reject(that._parseError(that.ERR_INVALID_USER)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Update a user if the email exists, or insert a new one if it doesn't | |
* @method module:Fizzmod.MasterData#insertUpdateUser | |
* @access public | |
* @param {string} email - The email of the user | |
* @param {Object} data - The data that will be updated. | |
* @param {string} [entity='CL'] - The Entity | |
* @returns {promise} | |
* @example | |
*Fizzmod.MasterData.insertUpdateUser("[email protected]", | |
* {document: 'xxxxxxxxxx', firstName: 'Master', lastName: 'of the Matrix'}).done(function(response) { | |
* if(response.isInsert()){ | |
* console.log("New user!"); | |
* }else if(response.isUpdate()){ | |
* console.log("User updated!"); | |
* } | |
*}).fail(function(error){ console.log(error); }); | |
*/ | |
insertUpdateUser: function(email, data, entity) { | |
var that = this; | |
return $.Deferred(function() { | |
var def = this; | |
if (!Utils.isEmail(email)) | |
return def.reject(that._parseError(that.ERR_INVALID_EMAIL)); | |
return that._getByEmail(email, entity).done(function(result) { | |
if (that._resultOK(result)) { | |
return that._partialUpdate(result[0].id, data, entity).done(function(result) { | |
def.resolve(that._parseResult(result, that.OP_UPDATE)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
} else { | |
return that._insert($.extend({ | |
email: email | |
}, data), entity).done(function(result) { | |
def.resolve(that._parseResult(result, that.OP_INSERT)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
} | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Insert a document | |
* @method module:Fizzmod.MasterData#insert | |
* @access public | |
* @param {Object} data - The data that will be inserted | |
* @param {string} entity - The entity of the document to insert | |
* @returns {promise} | |
*/ | |
insert: function(data, entity) { | |
var that = this; | |
return $.Deferred(function() { | |
var def = this; | |
return that._insert(data, entity).done(function(result) { | |
def.resolve(that._parseResult(result)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Insert/update a document | |
* @method module:Fizzmod.MasterData#insertUpdate | |
* @access public | |
* @param {string} id - The ID of the item that will be inserted/updated | |
* @param {Object} data - The data that will be inserted | |
* @param {string} entity - The entity of the document to insert | |
* @returns {promise} | |
*/ | |
insertUpdate: function(id, data, entity) { | |
var that = this; | |
return $.Deferred(function() { | |
var def = this; | |
return that._partialUpdate(id, data, entity).done(function(result) { | |
def.resolve(that._parseResult(result)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Performs a search | |
* @method module:Fizzmod.MasterData#search | |
* @param {Object} params - The search parameters | |
* @param {Array} fields - The Fields that will be retrieved | |
* @param {string} entity - The entity where the search will be performed | |
* @param {int} [limit=49] - The search limit | |
* @param {int} [offset=0] - The search offset | |
* @returns {promise} | |
*/ | |
search: function(params, fields, entity, limit, offset) { | |
var that = this; | |
return $.Deferred(function() { | |
var def = this; | |
return that._search(params, fields, entity, limit, offset).done(function(result) { | |
def.resolve(that._parseResult(result)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
/** | |
* Get a master data document | |
* @method module:Fizzmod.MasterData#get | |
* @param {string} id - The ID of the document to get | |
* @param {Array} [fields=["id"]] - A list of fields to retrieve, default values will always be retrieved | |
* @param {string} entity - The entity of the document to get | |
* @returns {promise} | |
*/ | |
get: function(id, fields, entity) { | |
var that = this; | |
return $.Deferred(function() { | |
var def = this; | |
return that._get(id, fields, entity).done(function(result) { | |
def.resolve(that._parseResult(result)); | |
}).fail(function(error) { | |
def.reject(that._parseError(error)); | |
}); | |
}).promise(); | |
}, | |
uploadFile: function(input) { | |
var files = input.files; | |
//TODO | |
} | |
}; //Master Data prototype | |
var MD = new MasterData(); //MasterData instance | |
return MD; //return Master Data instance | |
})(jQuery, window); | |
return new Fizzmod(); | |
})(jQuery, window); // End Fizzmod | |
if (typeof dataLayer !== "undefined") { | |
dataLayer.push({ | |
event: 'fizzmodLoaded' | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment