|
this.Shopify = this.Shopify || {}; |
|
this.Shopify.theme = this.Shopify.theme || {}; |
|
this.Shopify.theme.product = (function (exports) { |
|
'use strict'; |
|
|
|
/** |
|
* Find a match in the project JSON (using a ID number) and return the variant (as an Object) |
|
* @param {Object} product Product JSON object |
|
* @param {Number} value Accepts Number (e.g. 6908023078973) |
|
* @returns {Object} The variant object once a match has been successful. Otherwise null will be return |
|
*/ |
|
function getVariantFromId(product, value) { |
|
_validateProductStructure(product); |
|
|
|
if (typeof value !== 'number') { |
|
throw new TypeError(value + ' is not a Number.'); |
|
} |
|
|
|
var result = product.variants.filter(function(variant) { |
|
return variant.id === value; |
|
}); |
|
|
|
return result[0] || null; |
|
} |
|
|
|
/** |
|
* Convert the Object (with 'name' and 'value' keys) into an Array of values, then find a match & return the variant (as an Object) |
|
* @param {Object} product Product JSON object |
|
* @param {Object} collection Object with 'name' and 'value' keys (e.g. [{ name: "Size", value: "36" }, { name: "Color", value: "Black" }]) |
|
* @returns {Object || null} The variant object once a match has been successful. Otherwise null will be returned |
|
*/ |
|
function getVariantFromSerializedArray(product, collection) { |
|
_validateProductStructure(product); |
|
|
|
// If value is an array of options |
|
var optionArray = _createOptionArrayFromOptionCollection(product, collection); |
|
return getVariantFromOptionArray(product, optionArray); |
|
} |
|
|
|
/** |
|
* Find a match in the project JSON (using Array with option values) and return the variant (as an Object) |
|
* @param {Object} product Product JSON object |
|
* @param {Array} options List of submitted values (e.g. ['36', 'Black']) |
|
* @returns {Object || null} The variant object once a match has been successful. Otherwise null will be returned |
|
*/ |
|
function getVariantFromOptionArray(product, options) { |
|
_validateProductStructure(product); |
|
_validateOptionsArray(options); |
|
|
|
var result = product.variants.filter(function(variant) { |
|
return options.every(function(option, index) { |
|
return variant.options[index] === option; |
|
}); |
|
}); |
|
|
|
return result[0] || null; |
|
} |
|
|
|
/** |
|
* Creates an array of selected options from the object |
|
* Loops through the project.options and check if the "option name" exist (product.options.name) and matches the target |
|
* @param {Object} product Product JSON object |
|
* @param {Array} collection Array of object (e.g. [{ name: "Size", value: "36" }, { name: "Color", value: "Black" }]) |
|
* @returns {Array} The result of the matched values. (e.g. ['36', 'Black']) |
|
*/ |
|
function _createOptionArrayFromOptionCollection(product, collection) { |
|
_validateProductStructure(product); |
|
_validateSerializedArray(collection); |
|
|
|
var optionArray = []; |
|
|
|
collection.forEach(function(option) { |
|
for (var i = 0; i < product.options.length; i++) { |
|
if (product.options[i].name.toLowerCase() === option.name.toLowerCase()) { |
|
optionArray[i] = option.value; |
|
break; |
|
} |
|
} |
|
}); |
|
|
|
return optionArray; |
|
} |
|
|
|
/** |
|
* Check if the product data is a valid JS object |
|
* Error will be thrown if type is invalid |
|
* @param {Array} product Product JSON object |
|
*/ |
|
function _validateProductStructure(product) { |
|
if (typeof product !== 'object') { |
|
throw new TypeError(product + 'is not an object.'); |
|
} |
|
|
|
if (Object.keys(product).length === 0 && product.constructor === Object) { |
|
throw new Error(product + 'is empty.'); |
|
} |
|
} |
|
|
|
/** |
|
* Validate the structure of the array |
|
* It must be formatted like jQuery's serializeArray() |
|
* @param {Array} collection Array of object [{ name: "Size", value: "36" }, { name: "Color", value: "Black" }] |
|
*/ |
|
function _validateSerializedArray(collection) { |
|
if (!Array.isArray(collection)) { |
|
throw new TypeError(collection + 'is not an array.'); |
|
} |
|
|
|
if (collection.length === 0) { |
|
throw new Error(collection + 'is empty.'); |
|
} |
|
|
|
if (collection[0].hasOwnProperty('name')) { |
|
if (typeof collection[0].name !== 'string') { |
|
throw new TypeError( |
|
'Invalid value type passed for name of option ' + |
|
collection[0].name + |
|
'. Value should be string.' |
|
); |
|
} |
|
} else { |
|
throw new Error(collection[0] + 'does not contain name key.'); |
|
} |
|
} |
|
|
|
/** |
|
* Validate the structure of the array |
|
* It must be formatted as list of values |
|
* @param {Array} collection Array of object (e.g. ['36', 'Black']) |
|
*/ |
|
function _validateOptionsArray(options) { |
|
if (Array.isArray(options) && typeof options[0] === 'object') { |
|
throw new Error(options + 'is not a valid array of options.'); |
|
} |
|
} |
|
|
|
exports.getVariantFromId = getVariantFromId; |
|
exports.getVariantFromSerializedArray = getVariantFromSerializedArray; |
|
exports.getVariantFromOptionArray = getVariantFromOptionArray; |
|
|
|
return exports; |
|
|
|
}({})); |