Convert the basic variant option dropdowns on Shopify PDP to swatches.
let mSwatches = new magicSwatches();
mSwatches.render();
class magicSwatches { | |
constructor(config) { | |
config = typeof config == 'undefined' ? {} : config; | |
this.option_wrapper_selector = typeof config.option_wrapper != 'undefined' ? config.option_wrapper : '.selector-wrapper'; | |
this.product_form_selector = typeof config.product_form != 'undefined' ? config.product_form : 'form.product-form'; | |
this.strip_giftcard_values = typeof config.strip_giftcard_values != 'undefined' ? config.strip_giftcard_values : true; | |
this.form = document.querySelector(this.product_form_selector); | |
this.option_wrappers = document.querySelectorAll(this.option_wrapper_selector); | |
this.variant_selectbox = this.form.querySelector('[name="id"]'); | |
}; | |
triggerChangeEvent(element) { | |
if("createEvent" in document) { | |
var evt = document.createEvent("HTMLEvents"); | |
evt.initEvent("change", false, true); | |
element.dispatchEvent(evt); | |
} else { | |
element.fireEvent("onchange"); | |
} | |
} | |
render() { | |
let styles = []; | |
this.option_wrappers.forEach((option_wrapper, i) => { | |
let selectbox = option_wrapper.querySelector('select'), | |
nodeInnerHTML = ''; | |
selectbox.setAttribute('data-optionuid', `ms-option-selectbox-${i}`); | |
selectbox.querySelectorAll('option').forEach((option) => { | |
let activeClass = selectbox.value == option.getAttribute('value') ? ' class="active-option"' : '', | |
optionDisplayValue = this.strip_giftcard_values && window.location.href.indexOf('gift') > -1 && window.location.href.indexOf('card') > -1 ? option.getAttribute('value').replace(/[^\d.-]/g, '').replace('.00', '') : option.getAttribute('value'); | |
nodeInnerHTML = `${nodeInnerHTML}<span${activeClass} data-option="${option.getAttribute('value')}">${optionDisplayValue}</span>`; | |
}); | |
styles.push(`.swatch-selector[data-optionuid="ms-option-selectbox-${i}"] { line-height: ${selectbox.offsetHeight}px; min-height: ${selectbox.offsetHeight}px }`); | |
selectbox.style.display = 'none'; | |
let newNode = document.createElement('div'); | |
newNode.setAttribute('class', 'swatch-selector'); | |
newNode.setAttribute('data-optionuid', `ms-option-selectbox-${i}`); | |
newNode.innerHTML = nodeInnerHTML; | |
selectbox.parentElement.insertBefore(newNode, selectbox); | |
}); | |
document.querySelectorAll(`.swatch-selector span[data-option]`).forEach((swatchOptionSpan) => { | |
swatchOptionSpan.addEventListener('click', (e) => { | |
e.preventDefault(); | |
let swatchOption = e.target, | |
swatchValue = swatchOption.getAttribute('data-option'), | |
swatchSelectbox = document.querySelector(`select[data-optionuid="${swatchOptionSpan.parentElement.getAttribute('data-optionuid')}"]`); | |
swatchOption.parentElement.querySelectorAll('span').forEach((opt) => { | |
if(opt.getAttribute('data-option') == swatchValue) { | |
opt.classList.add('active-option'); | |
} else { | |
opt.classList.remove('active-option'); | |
} | |
}); | |
swatchSelectbox.value = swatchValue; | |
this.triggerChangeEvent(swatchSelectbox); | |
}, false); | |
}); | |
let basicStyles = [ | |
'.swatch-selector { display: flex; flex-wrap: wrap; margin-left: -.25em; margin-right: -.25em }', | |
'.swatch-selector span { border: 1px solid #DDD; border-radius: 4px; cursor: pointer; margin: .25em; padding: 0 1em }', | |
'.swatch-selector span:hover { border-color: #666; box-shadow: -2px -2px 5px rgba(0,0,0,0.15) inset }', | |
'.swatch-selector span.active-option { background-color: #666; border-color: #333; box-shadow: -2px -2px 5px rgba(0,0,0,0.15) inset; color: #FFF }' | |
]; | |
let styleSheetElement = document.createElement('style'); | |
styleSheetElement.setAttribute('type', 'text/css'); | |
styleSheetElement.innerHTML = basicStyles.join('') + styles.join(''); | |
document.getElementsByTagName('head')[0].appendChild(styleSheetElement); | |
}; | |
}; |