Skip to content

Instantly share code, notes, and snippets.

@trungnus96
Forked from patrickbolle/index.js
Created July 9, 2022 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trungnus96/398eb98d3ccf8b5694e8829df1a507f2 to your computer and use it in GitHub Desktop.
Save trungnus96/398eb98d3ccf8b5694e8829df1a507f2 to your computer and use it in GitHub Desktop.
Shopify JS Variant Listener
/**
* This class contains general helper methods.
*/
class Helper {
/**
* @param {String} name
* @returns {String|null}
*/
static getQueryParameter(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]')
const regex = new RegExp('[\\?&]' + name + '=([^&#]*)')
const results = regex.exec(location.search)
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '))
}
}
/**
* This class contains Shopify related helper methods.
*/
class ShopifyHelper {
/**
* @returns {String|null}
*/
static getSelectedVariantId() {
// Try to get variant id from form element with name id
const addToCartForm = document.querySelector('form[action^="/cart/add"]')
if (addToCartForm) {
const input = addToCartForm.querySelector('[name="id"]')
const submitButton = addToCartForm.querySelector('[type="submit"]')
// If the submit button is disabled, the input value is most likely wrong
// because it got autofilled on initial page load with the first available product variant id.
if (
(!submitButton || submitButton.disabled !== true) &&
input &&
input.value
) {
return input.value
}
}
// Try to get variant id from "variant" query parameter.
const queryParameter = Helper.getQueryParameter('variant')
if (queryParameter) {
return queryParameter
}
// Try to get variant id from ShopifyAnalytics.meta object
if (
self.ShopifyAnalytics &&
self.ShopifyAnalytics.meta &&
self.ShopifyAnalytics.meta.selectedVariantId
) {
return self.ShopifyAnalytics.meta.selectedVariantId
}
// No variant id found
return null
}
/**
* @returns {Array<Element>}
*/
static getAddToCartFormElements() {
const foundElements = []
const elementTypes = ['select', 'input']
for (let elementType of elementTypes) {
let elements = document.querySelectorAll(`form[action^="/cart/add"] ${elementType}`)
for (let element of elements) {
foundElements.push(element)
}
}
return foundElements
}
/**
* @param {Function} eventHandler
*/
static addVariantListeners(eventHandler) {
for (let element of ShopifyHelper.getAddToCartFormElements()) {
element.addEventListener('change', eventHandler)
}
}
/**
* @param {Function} eventHandler
*/
static removeVariantListeners(eventHandler) {
for (let element of ShopifyHelper.getAddToCartFormElements()) {
element.removeEventListener('change', eventHandler)
}
}
}
const initApp = () => {
let selectedVariantId = ShopifyHelper.getSelectedVariantId()
console.log('selected variant id is', selectedVariantId)
const variantHandler = (event) => {
const variantId = ShopifyHelper.getSelectedVariantId()
if (selectedVariantId !== variantId) {
selectedVariantId = variantId
console.log('selected variant id changed to', selectedVariantId)
}
}
ShopifyHelper.addVariantListeners(variantHandler)
}
if (document.readyState !== 'loading') {
setTimeout(initApp, 0)
} else {
document.addEventListener('DOMContentLoaded', initApp)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment