Advertisement
Guest User

Untitled

a guest
Feb 20th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. if ((typeof Shopify) == 'undefined') {
  2.   var Shopify = {};
  3. }
  4.  
  5.  
  6. // ---------------------------------------------------------------------------
  7. // Shopify generic helper methods
  8. // ---------------------------------------------------------------------------
  9. Shopify.each = function(ary, callback) {
  10.   for (var i = 0; i < ary.length; i++) {
  11.     callback(ary[i], i);
  12.   }
  13. };
  14.  
  15. Shopify.map = function(ary, callback) {
  16.   var result = [];
  17.   for (var i = 0; i < ary.length; i++) {
  18.     result.push(callback(ary[i], i));
  19.   }
  20.   return result;
  21. };
  22.  
  23. Shopify.arrayIncludes = function(ary, obj) {
  24.   for (var i = 0; i < ary.length; i++) {
  25.     if (ary[i] == obj) {
  26.       return true;
  27.     }
  28.   }
  29.   return false;
  30. };
  31.  
  32. Shopify.uniq = function(ary) {
  33.   var result = [];
  34.   for (var i = 0; i < ary.length; i++) {
  35.     if (!Shopify.arrayIncludes(result, ary[i])) { result.push(ary[i]); }
  36.   }
  37.   return result;
  38. };
  39.  
  40. Shopify.isDefined = function(obj) {
  41.   return ((typeof obj == 'undefined') ? false : true);
  42. };
  43.  
  44. Shopify.getClass = function(obj) {
  45.   return Object.prototype.toString.call(obj).slice(8, -1);
  46. };
  47.  
  48. Shopify.extend = function(subClass, baseClass) {
  49.   function inheritance() {}
  50.   inheritance.prototype = baseClass.prototype;
  51.  
  52.   subClass.prototype = new inheritance();
  53.   subClass.prototype.constructor = subClass;
  54.   subClass.baseConstructor = baseClass;
  55.   subClass.superClass = baseClass.prototype;
  56. };
  57.  
  58. Shopify.urlParam = function(name) {
  59.   var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
  60.   return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
  61. }
  62.  
  63.  
  64.  
  65. // ---------------------------------------------------------------------------
  66. // Shopify Product object
  67. // JS representation of Product
  68. // ---------------------------------------------------------------------------
  69. Shopify.Product = function(json) {
  70.   if (Shopify.isDefined(json)) { this.update(json); }
  71. };
  72.  
  73. Shopify.Product.prototype.update = function(json) {
  74.   for (property in json) {
  75.     this[property] = json[property];
  76.   }
  77. };
  78.  
  79. // returns array of option names for product
  80. Shopify.Product.prototype.optionNames = function() {
  81.   if (Shopify.getClass(this.options) == 'Array') {
  82.     return this.options;
  83.   } else {
  84.     return [];
  85.   }
  86. };
  87.  
  88. // returns array of all option values (in order) for a given option name index
  89. Shopify.Product.prototype.optionValues = function(index) {
  90.   if (!Shopify.isDefined(this.variants)) { return null; }
  91.   var results = Shopify.map(this.variants, function(e) {
  92.     var option_col = "option" + (index+1);
  93.     return (e[option_col] == undefined) ? null : e[option_col];
  94.   });
  95.   return (results[0] == null ? null : Shopify.uniq(results));
  96. };
  97.  
  98. // return the variant object if exists with given values, otherwise return null
  99. Shopify.Product.prototype.getVariant = function(selectedValues) {
  100.   var found = null;
  101.   if (selectedValues.length != this.options.length) { return found; }
  102.  
  103.   Shopify.each(this.variants, function(variant) {
  104.     var satisfied = true;
  105.     for (var j = 0; j < selectedValues.length; j++) {
  106.       var option_col = "option"+(j+1);
  107.       if (variant[option_col] != selectedValues[j]) {
  108.         satisfied = false;
  109.       }
  110.     }
  111.     if (satisfied == true) {
  112.       found = variant;
  113.       return;
  114.     }
  115.   });
  116.   return found;
  117. };
  118.  
  119. Shopify.Product.prototype.getVariantById = function(id) {
  120.   for (var i = 0; i < this.variants.length; i++) {
  121.     var variant = this.variants[i];
  122.  
  123.     if (id == variant.id) {
  124.       return variant;
  125.     }
  126.   }
  127.  
  128.   return null;
  129. }
  130.  
  131. // ---------------------------------------------------------------------------
  132. // Money format handler
  133. // ---------------------------------------------------------------------------
  134. Shopify.money_format = "${{amount}}";
  135. Shopify.formatMoney = function(cents, format) {
  136.   if (typeof cents == 'string') { cents = cents.replace('.',''); }
  137.   var value = '';
  138.   var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
  139.   var formatString = (format || this.money_format);
  140.  
  141.   function defaultOption(opt, def) {
  142.      return (typeof opt == 'undefined' ? def : opt);
  143.   }
  144.  
  145.   function formatWithDelimiters(number, precision, thousands, decimal) {
  146.     precision = defaultOption(precision, 2);
  147.     thousands = defaultOption(thousands, ',');
  148.     decimal   = defaultOption(decimal, '.');
  149.  
  150.     if (isNaN(number) || number == null) { return 0; }
  151.  
  152.     number = (number/100.0).toFixed(precision);
  153.  
  154.     var parts   = number.split('.'),
  155.         dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands),
  156.         cents   = parts[1] ? (decimal + parts[1]) : '';
  157.  
  158.     return dollars + cents;
  159.   }
  160.  
  161.   switch(formatString.match(placeholderRegex)[1]) {
  162.     case 'amount':
  163.       value = formatWithDelimiters(cents, 2);
  164.       break;
  165.     case 'amount_no_decimals':
  166.       value = formatWithDelimiters(cents, 0);
  167.       break;
  168.     case 'amount_with_comma_separator':
  169.       value = formatWithDelimiters(cents, 2, '.', ',');
  170.       break;
  171.     case 'amount_no_decimals_with_comma_separator':
  172.       value = formatWithDelimiters(cents, 0, '.', ',');
  173.       break;
  174.   }
  175.  
  176.   return formatString.replace(placeholderRegex, value);
  177. }
  178.  
  179. function floatToString(numeric, decimals) {
  180.   var amount = numeric.toFixed(decimals).toString();
  181.   if(amount.match(/^\.\d+/)) {return "0"+amount; }
  182.   else { return amount; }
  183. };
  184. // ---------------------------------------------------------------------------
  185. // OptionSelectors(domid, options)
  186. //
  187. // ---------------------------------------------------------------------------
  188. Shopify.OptionSelectors = function(existingSelectorId, options) {
  189.   this.selectorDivClass       = 'selector-wrapper';
  190.   this.selectorClass          = 'single-option-selector';
  191.   this.variantIdFieldIdSuffix = '-variant-id';
  192.  
  193.   this.variantIdField    = null;
  194.   this.historyState      = null;
  195.   this.selectors         = [];
  196.   this.domIdPrefix       = existingSelectorId;
  197.   this.product           = new Shopify.Product(options.product);
  198.   this.onVariantSelected = Shopify.isDefined(options.onVariantSelected) ? options.onVariantSelected : function(){};
  199.  
  200.   this.replaceSelector(existingSelectorId); // create the dropdowns
  201.   this.initDropdown();
  202.  
  203.   if (options.enableHistoryState) {
  204.     this.historyState = new Shopify.OptionSelectors.HistoryState(this);
  205.   }
  206.  
  207.   return true;
  208. };
  209.  
  210. Shopify.OptionSelectors.prototype.initDropdown = function () {
  211.   var options = {initialLoad: true};
  212.   var successDropdownSelection = this.selectVariantFromDropdown(options);
  213.  
  214.   if (!successDropdownSelection) {
  215.     var self = this;
  216.     setTimeout(function () {
  217.       if (!self.selectVariantFromParams(options)) {
  218.         self.fireOnChangeForFirstDropdown.call(self, options);
  219.       }
  220.     });
  221.   }
  222. };
  223.  
  224. Shopify.OptionSelectors.prototype.fireOnChangeForFirstDropdown = function (options) {
  225.   this.selectors[0].element.onchange(options);
  226. };
  227.  
  228. Shopify.OptionSelectors.prototype.selectVariantFromParamsOrDropdown = function (options) {
  229.   var success = this.selectVariantFromParams(options)
  230.  
  231.   if (!success) {
  232.     this.selectVariantFromDropdown(options);
  233.   }
  234. };
  235.  
  236. // insert new multi-selectors and hide original selector
  237. Shopify.OptionSelectors.prototype.replaceSelector = function(domId) {
  238.   var oldSelector = document.getElementById(domId);
  239.   var parent = oldSelector.parentNode;
  240.   Shopify.each(this.buildSelectors(), function(el) {
  241.     parent.insertBefore(el, oldSelector);
  242.   });
  243.   oldSelector.style.display = 'none';
  244.   this.variantIdField = oldSelector;
  245. };
  246.  
  247. Shopify.OptionSelectors.prototype.selectVariantFromDropdown = function (options) {
  248.   var option = document.getElementById(this.domIdPrefix).querySelector("[selected]");
  249.  
  250.   if (!option) {
  251.     return false;
  252.   }
  253.  
  254.   var variantId = option.value;
  255.   return this.selectVariant(variantId, options);
  256. };
  257.  
  258. Shopify.OptionSelectors.prototype.selectVariantFromParams = function (options) {
  259.   var variantId = Shopify.urlParam("variant");
  260.   return this.selectVariant(variantId, options);
  261. };
  262.  
  263. Shopify.OptionSelectors.prototype.selectVariant = function (variantId, options) {
  264.   var variant  = this.product.getVariantById(variantId);
  265.  
  266.   if (variant == null) {
  267.     return false;
  268.   }
  269.  
  270.   for (var i = 0; i < this.selectors.length; i++) {
  271.     var element = this.selectors[i].element;
  272.     var optionName = element.getAttribute("data-option")
  273.     var value = variant[optionName];
  274.     if (value == null || !this.optionExistInSelect(element, value)) {
  275.       continue;
  276.     }
  277.  
  278.     element.value = value;
  279.   }
  280.  
  281.   if (typeof jQuery !== 'undefined') {
  282.     jQuery(this.selectors[0].element).trigger('change', options);
  283.   } else {
  284.     this.selectors[0].element.onchange(options);
  285.   }
  286.  
  287.   return true;
  288. };
  289.  
  290. Shopify.OptionSelectors.prototype.optionExistInSelect = function (select, value) {
  291.   for (var i = 0; i < select.options.length; i++) {
  292.     if (select.options[i].value == value) {
  293.       return true;
  294.     }
  295.   }
  296. };
  297.  
  298. // insertSelectors(domId, msgDomId)
  299. // create multi-selectors in the given domId, and use msgDomId to show messages
  300. Shopify.OptionSelectors.prototype.insertSelectors = function(domId, messageElementId) {
  301.   if (Shopify.isDefined(messageElementId)) { this.setMessageElement(messageElementId); }
  302.  
  303.   this.domIdPrefix = "product-" + this.product.id + "-variant-selector";
  304.  
  305.   var parent = document.getElementById(domId);
  306.   Shopify.each(this.buildSelectors(), function(el) {
  307.     parent.appendChild(el);
  308.   });
  309. };
  310.  
  311. // buildSelectors(index)
  312. // create and return new selector element for given option
  313. Shopify.OptionSelectors.prototype.buildSelectors = function() {
  314.   // build selectors
  315.   for (var i = 0; i < this.product.optionNames().length; i++) {
  316.     var sel = new Shopify.SingleOptionSelector(this, i, this.product.optionNames()[i], this.product.optionValues(i));
  317.     sel.element.disabled = false;
  318.     this.selectors.push(sel);
  319.   }
  320.  
  321.   // replace existing selector with new selectors, new hidden input field, new hidden messageElement
  322.   var divClass = this.selectorDivClass;
  323.   var optionNames = this.product.optionNames();
  324.   var elements = Shopify.map(this.selectors, function(selector) {
  325.     var div = document.createElement('div');
  326.     div.setAttribute('class', divClass);
  327.     // create label if more than 1 option (ie: more than one drop down)
  328.     if (optionNames.length > 1) {
  329.       // create and appened a label into div
  330.       var label = document.createElement('label');
  331.       label.htmlFor = selector.element.id;
  332.       label.innerHTML = selector.name;
  333.       div.appendChild(label);
  334.     }
  335.     div.appendChild(selector.element);
  336.     return div;
  337.   });
  338.  
  339.   return elements;
  340. };
  341.  
  342. // returns array of currently selected values from all multiselectors
  343. Shopify.OptionSelectors.prototype.selectedValues = function() {
  344.   var currValues = [];
  345.   for (var i = 0; i < this.selectors.length; i++) {
  346.     var thisValue = this.selectors[i].element.value;
  347.     currValues.push(thisValue);
  348.   }
  349.   return currValues;
  350. };
  351.  
  352. // callback when a selector is updated.
  353. Shopify.OptionSelectors.prototype.updateSelectors = function(index, options) {
  354.   var currValues = this.selectedValues(); // get current values
  355.   var variant    = this.product.getVariant(currValues);
  356.   if (variant) {
  357.     this.variantIdField.disabled = false;
  358.     this.variantIdField.value = variant.id; // update hidden selector with new variant id
  359.   } else {
  360.     this.variantIdField.disabled = true;
  361.   }
  362.  
  363.   this.onVariantSelected(variant, this, options);  // callback
  364.  
  365.   if (this.historyState != null) {
  366.     this.historyState.onVariantChange(variant, this, options);
  367.   }
  368. };
  369.  
  370. // ---------------------------------------------------------------------------
  371. // OptionSelectorsFromDOM(domid, options)
  372. //
  373. // ---------------------------------------------------------------------------
  374.  
  375. Shopify.OptionSelectorsFromDOM = function(existingSelectorId, options){
  376.   // build product json from selectors
  377.   // create new options hash
  378.   var optionNames = options.optionNames || [];
  379.   var priceFieldExists = options.priceFieldExists || true;
  380.   var delimiter = options.delimiter || '/';
  381.   var productObj = this.createProductFromSelector(existingSelectorId, optionNames, priceFieldExists, delimiter);
  382.   options.product = productObj;
  383.   Shopify.OptionSelectorsFromDOM.baseConstructor.call(this, existingSelectorId, options);
  384. };
  385.  
  386. Shopify.extend(Shopify.OptionSelectorsFromDOM, Shopify.OptionSelectors);
  387.  
  388. // updates the product_json from existing select element
  389. Shopify.OptionSelectorsFromDOM.prototype.createProductFromSelector = function(domId, optionNames, priceFieldExists, delimiter) {
  390.   if (!Shopify.isDefined(priceFieldExists)) { var priceFieldExists = true; }
  391.   if (!Shopify.isDefined(delimiter)) { var delimiter = '/'; }
  392.  
  393.   var oldSelector = document.getElementById(domId);
  394.   var options = oldSelector.childNodes;
  395.   var parent = oldSelector.parentNode;
  396.  
  397.   var optionCount = optionNames.length;
  398.  
  399.   // build product json + messages array
  400.   var variants = [];
  401.   var self = this;
  402.   Shopify.each(options, function(option, variantIndex) {
  403.     if (option.nodeType == 1 && option.tagName.toLowerCase() == 'option') {
  404.       var chunks = option.innerHTML.split(new RegExp('\\s*\\'+ delimiter +'\\s*'));
  405.  
  406.       if (optionNames.length == 0) {
  407.         optionCount = chunks.length - (priceFieldExists ? 1 : 0);
  408.       }
  409.  
  410.       var optionOptionValues = chunks.slice(0, optionCount);
  411.       var message = (priceFieldExists ? chunks[optionCount] : '');
  412.       var variantId = option.getAttribute('value');
  413.  
  414.       var attributes = {
  415.         available: (option.disabled ? false : true),
  416.         id:  parseFloat(option.value),
  417.         price: message,
  418.         option1: optionOptionValues[0],
  419.         option2: optionOptionValues[1],
  420.         option3: optionOptionValues[2]
  421.       };
  422.       variants.push(attributes);
  423.     }
  424.   });
  425.   var updateObj = { variants: variants };
  426.   if (optionNames.length == 0) {
  427.     updateObj.options = [];
  428.     for (var i=0;i<optionCount;i++) { updateObj.options[i] = ('option ' + (i + 1)) }
  429.   } else {
  430.     updateObj.options = optionNames;
  431.   }
  432.   return updateObj;
  433. };
  434.  
  435.  
  436. // ---------------------------------------------------------------------------
  437. // SingleOptionSelector
  438. // takes option name and values and creates a option selector from them
  439. // ---------------------------------------------------------------------------
  440. Shopify.SingleOptionSelector = function(multiSelector, index, name, values) {
  441.   this.multiSelector = multiSelector;
  442.   this.values = values;
  443.   this.index = index;
  444.   this.name = name;
  445.   this.element = document.createElement('select');
  446.   for (var i = 0; i < values.length; i++) {
  447.     var opt = document.createElement('option');
  448.     opt.value = values[i];
  449.     opt.innerHTML = values[i];
  450.     this.element.appendChild(opt);
  451.   }
  452.   this.element.setAttribute('class', this.multiSelector.selectorClass);
  453.   this.element.setAttribute('data-option', 'option' + (index+1));
  454.   this.element.id = multiSelector.domIdPrefix + '-option-' + index;
  455.   this.element.onchange = function(event, options) {
  456.     options = options || {};
  457.  
  458.     multiSelector.updateSelectors(index, options);
  459.   };
  460.  
  461.   return true;
  462. };
  463.  
  464. // ---------------------------------------------------------------------------
  465. // Image.switchImage
  466. // helps to switch variant images on variant selection
  467. // ---------------------------------------------------------------------------
  468. Shopify.Image = {
  469.  
  470.   preload: function (images, size) {
  471.     for (var i=0; i < images.length; i++) {
  472.       var image = images[i];
  473.  
  474.       this.loadImage(this.getSizedImageUrl(image, size));
  475.     }
  476.   },
  477.  
  478.   loadImage: function (path) {
  479.     new Image().src = path;
  480.   },
  481.  
  482.   switchImage: function (image, element, callback) {
  483.     if (!image || !element) {
  484.       return;
  485.     }
  486.  
  487.     var size = this.imageSize(element.src)
  488.     var imageUrl = this.getSizedImageUrl(image.src, size);
  489.  
  490.     if (callback) {
  491.       callback(imageUrl, image, element);
  492.     } else {
  493.       element.src = imageUrl;
  494.     }
  495.   },
  496.  
  497.   imageSize: function (src) {
  498.     var match = src.match(/_(1024x1024|2048x2048|pico|icon|thumb|small|compact|medium|large|grande)\./);
  499.  
  500.     if (match != null) {
  501.       return match[1];
  502.     } else {
  503.       return null;
  504.     }
  505.   },
  506.  
  507.   getSizedImageUrl: function (src, size) {
  508.     if (size == null) {
  509.       return src;
  510.     }
  511.  
  512.     if (size == 'master') {
  513.       return this.removeProtocol(src);
  514.     }
  515.  
  516.     var match  = src.match(/\.(jpg|jpeg|gif|png|bmp|bitmap|tiff|tif)(\?v=\d+)?$/i);
  517.  
  518.     if (match != null) {
  519.       var prefix = src.split(match[0]);
  520.       var suffix = match[0];
  521.  
  522.       return this.removeProtocol(prefix[0] + "_" + size + suffix);
  523.     } else {
  524.       return null;
  525.     }
  526.   },
  527.  
  528.   removeProtocol: function (path) {
  529.     return path.replace(/http(s)?:/, "");
  530.   }
  531. };
  532.  
  533. // ---------------------------------------------------------------------------
  534. // Shopify.HistoryState
  535. // Gets events from Push State
  536. // ---------------------------------------------------------------------------
  537.  
  538. Shopify.OptionSelectors.HistoryState = function (optionSelector) {
  539.   if (this.browserSupports()) {
  540.     this.register(optionSelector);
  541.   }
  542. };
  543.  
  544. Shopify.OptionSelectors.HistoryState.prototype.register = function (optionSelector) {
  545.   window.addEventListener("popstate", function(event) {
  546.     optionSelector.selectVariantFromParamsOrDropdown({popStateCall: true});
  547.   });
  548. };
  549.  
  550. Shopify.OptionSelectors.HistoryState.prototype.onVariantChange = function (variant, selector, data) {
  551.   if (this.browserSupports()) {
  552.     if (variant && !data.initialLoad && !data.popStateCall) {
  553.       window.history.replaceState({}, document.title, "?variant=" + variant.id);
  554.     }
  555.   }
  556. };
  557.  
  558. Shopify.OptionSelectors.HistoryState.prototype.browserSupports = function () {
  559.   return window.history && window.history.replaceState;
  560. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement