We had an issue with the 'active' class not working properly on attribute swatches. So I was given a fix from support which fixed the issue.
But then we wanted to implement the fix for volume pricing tables to work on products with variants so we implemented that fix (https://github.com/mivaecommerce/rea...ws/issues/83):
But the volume pricing fix broke the active swatch fix. How can the code be fixed so that both the swatches and volume pricing tables work properly?
Code:
AttributeMachine.prototype.Generate_Discount = function (discount) { var discount_div; discount_div = document.createElement('div'); discount_div.innerHTML = discount.descrip + ': ' + discount.formatted_discount; return discount_div; }; AttributeMachine.prototype.Generate_Swatch = function (product_code, attribute, option) { var swatch_container = document.querySelector('#&mvt:attributemachine:swa tch_element_id;'); var swatch = document.createElement('li'); var img = document.createElement('img'); img.src = option.image; img.setAttribute('alt', option.prompt); img.setAttribute('title', option.prompt); swatch.classList.add('o-list-inline__item'); swatch.setAttribute('data-code', option.code); swatch.setAttribute('data-color', option.prompt); swatch.appendChild(img); setTimeout(function () { if (swatch_container) { var swatch_element = swatch_container.querySelector('ul'); var swatch_select = document.querySelector('[data-hook="attribute-swatch-select"]'); var swatch_selected = swatch_select.options[swatch_select.selectedIndex].text; var swatch_name_element = document.querySelector('[data-hook="attribute-swatch-name"]'); var swatchElements = swatch_element.querySelectorAll('li'); swatch_element.removeAttribute('style'); swatch_element.classList.add('o-list-inline'); /** * Adds the selected swatch name to the label. */ swatch_name_element.textContent = swatch_selected; /** * Adds an active class to the selected swatch. */ swatchElements.forEach(function (swatchElement) { var swatchColor = swatchElement.getAttribute('data-code'); var swatchImage = swatchElement.querySelector('img'); if (swatchColor === swatch_select.options[swatch_select.selectedIndex].value) { swatchImage.classList.add('x-product-layout-purchase__swatches--active'); } else { swatchImage.classList.remove('x-product-layout-purchase__swatches--active'); } }); } }, 0); return swatch; }; AttributeMachine.prototype.Swatch_Click = function(input, attribute, option) { var swatch_name_element = document.querySelector('[data-hook="attribute-swatch-name"]'); var i; for (i = 0; i < input.select.options.length; i++) { if (input.select.options[i].value === option.code) { input.select.selectedIndex = i; } } if (attribute.inventory) { this.Attribute_Changed(input); } swatch_name_element.innerHTML = option.prompt; this.Generate_Swatch(input, attribute, option); };
Code:
AttributeMachine.prototype.Generate_Discount = function (discount) { let discount_div; discount_div = document.createElement('div'); discount_div.innerHTML = discount.descrip + ': ' + discount.formatted_discount; return discount_div; }; AttributeMachine.prototype.Generate_Swatch = function (product_code, attribute, option) { let swatch_container = document.querySelector('#&mvt:attributemachine:swa tch_element_id;'); let swatch = document.createElement('li'); let swatchButton = document.createElement('button'); let img = document.createElement('img'); img.src = option.image; img.setAttribute('alt', option.prompt); img.setAttribute('loading', 'lazy'); swatchButton.setAttribute('type', 'button'); swatchButton.setAttribute('aria-label', option.prompt); swatchButton.appendChild(img); swatch.classList.add('o-list-inline__item'); swatch.setAttribute('data-code', option.code); swatch.setAttribute('data-color', option.prompt); swatch.appendChild(swatchButton); setTimeout(function () { if (swatch_container) { let swatch_element = swatch_container.querySelector('ul'); let swatch_select = document.querySelector('[data-hook="attribute-swatch-select"]'); let swatch_selected = swatch_select.options[swatch_select.selectedIndex].text; let swatch_name_element = document.querySelector('[data-hook="attribute-swatch-name"]'); let swatchElements = swatch_element.querySelectorAll('li'); swatch_element.removeAttribute('style'); swatch_element.classList.add('o-list-inline'); /** * Adds the selected swatch name to the label. */ swatch_name_element.textContent = swatch_selected; /** * Adds an active class to the selected swatch. */ swatchElements.forEach(function (swatchElement) { let swatchColor = swatchElement.getAttribute('data-code'); let swatchImage = swatchElement.querySelector('button'); if (swatchColor === swatch_select.options[swatch_select.selectedIndex].value) { swatchImage.classList.add('x-product-layout-purchase__swatches--active'); } }); } }, 0); return swatch; }; AttributeMachine.prototype.Swatch_Click = function(input, attribute, option) { let swatch_name_element = document.querySelector('[data-hook="attribute-swatch-name"]'); let i; let swatchElements = input.machine.swatches.childNodes[0].childNodes; for (i = 0; i < input.select.options.length; i++) { if (input.select.options[i].value === option.code) { input.select.selectedIndex = i; } } if (attribute.inventory) { this.Attribute_Changed(input); } swatch_name_element.innerHTML = option.prompt; /** * Adds focus back to the selected swatch. */ swatchElements.forEach(function (swatchElement) { let swatchColor = swatchElement.getAttribute('data-code'); let swatchImage = swatchElement.querySelector('button'); if (swatchColor === input.select.options[input.select.selectedIndex].value) { swatchImage.focus(); } }); }; MivaEvents.SubscribeToEvent('variant_changed', function (data) { AJAX_Call_Module(Update_Volume_Pricing, 'runtime', 'discount_volume', 'Runtime_VolumePricing_Load_Product_Variant', 'Product_Code=' + encodeURIComponent(data.product_code) + '&' + 'Variant_ID=' + encodeURIComponent(data.variant_id)); }); const Update_Volume_Pricing = function (priceData) { const volumePricingContainer = document.querySelector('[data-volume-pricing]'); if (priceData.success === 1) { volumePricingContainer.innerHTML = [ '<table class="o-table o-table--fixed c-table-simple">', '<thead>', '<tr class="c-table-simple__row">', '<th class="c-table-simple__cell">Quantity</th>', '<th class="c-table-simple__cell">Price</th>', '</tr>', '</thead>', '<tbody data-pricing-grid>', '</tbody>', '</table>' ].join(''); let tableBody = volumePricingContainer.querySelector('[data-pricing-grid]'); priceData.data.forEach(function (entry) { const pricingRow = document.createElement('tr'); const quantityCell = document.createElement('td'); const priceCell = document.createElement('td'); pricingRow.classList.add('c-table-simple__row'); quantityCell.classList.add('c-table-simple__cell'); priceCell.classList.add('c-table-simple__cell'); if (entry.low === entry.high) { quantityCell.innerText = entry.low; } else if (entry.high) { quantityCell.innerText = entry.low + ' - ' + entry.high; } else { quantityCell.innerText = entry.low + '+'; } priceCell.innerText = entry.formatted_price; pricingRow.append(quantityCell, priceCell); tableBody.append(pricingRow); }); } else { volumePricingContainer.innerHTML = ''; } }; AttributeMachine.prototype.Generate_Discount = function (discount) { let discount_div; discount_div = document.createElement('div'); discount_div.innerHTML = discount.descrip + ': ' + discount.formatted_discount; return discount_div; }; AttributeMachine.prototype.Generate_Swatch = function (product_code, attribute, option) { let swatch_container = document.querySelector('#&mvt:attributemachine:swa tch_element_id;'); let swatch = document.createElement('li'); let swatchButton = document.createElement('button'); let img = document.createElement('img'); img.src = option.image; img.setAttribute('alt', option.prompt); img.setAttribute('loading', 'lazy'); swatchButton.setAttribute('type', 'button'); swatchButton.setAttribute('aria-label', option.prompt); swatchButton.appendChild(img); swatch.classList.add('o-list-inline__item'); swatch.setAttribute('data-code', option.code); swatch.setAttribute('data-color', option.prompt); swatch.appendChild(swatchButton); setTimeout(function () { if (swatch_container) { let swatch_element = swatch_container.querySelector('ul'); let swatch_select = document.querySelector('[data-hook="attribute-swatch-select"]'); let swatch_selected = swatch_select.options[swatch_select.selectedIndex].text; let swatch_name_element = document.querySelector('[data-hook="attribute-swatch-name"]'); let swatchElements = swatch_element.querySelectorAll('li'); swatch_element.removeAttribute('style'); swatch_element.classList.add('o-list-inline'); /** * Adds the selected swatch name to the label. */ swatch_name_element.textContent = swatch_selected; /** * Adds an active class to the selected swatch. */ swatchElements.forEach(function (swatchElement) { let swatchColor = swatchElement.getAttribute('data-code'); let swatchImage = swatchElement.querySelector('button'); if (swatchColor === swatch_select.options[swatch_select.selectedIndex].value) { swatchImage.classList.add('x-product-layout-purchase__swatches--active'); } }); } }, 0); return swatch; }; AttributeMachine.prototype.Swatch_Click = function(input, attribute, option) { let swatch_name_element = document.querySelector('[data-hook="attribute-swatch-name"]'); let i; let swatchElements = input.machine.swatches.childNodes[0].childNodes; for (i = 0; i < input.select.options.length; i++) { if (input.select.options[i].value === option.code) { input.select.selectedIndex = i; } } if (attribute.inventory) { this.Attribute_Changed(input); } swatch_name_element.innerHTML = option.prompt; /** * Adds focus back to the selected swatch. */ swatchElements.forEach(function (swatchElement) { let swatchColor = swatchElement.getAttribute('data-code'); let swatchImage = swatchElement.querySelector('button'); if (swatchColor === input.select.options[input.select.selectedIndex].value) { swatchImage.focus(); } }); }; MivaEvents.SubscribeToEvent('variant_changed', function (data) { AJAX_Call_Module(Update_Volume_Pricing, 'runtime', 'discount_volume', 'Runtime_VolumePricing_Load_Product_Variant', 'Product_Code=' + encodeURIComponent(data.product_code) + '&' + 'Variant_ID=' + encodeURIComponent(data.variant_id)); }); const Update_Volume_Pricing = function (priceData) { const volumePricingContainer = document.querySelector('[data-volume-pricing]'); if (priceData.success === 1) { volumePricingContainer.innerHTML = [ '<table class="o-table o-table--fixed c-table-simple">', '<thead>', '<tr class="c-table-simple__row">', '<th class="c-table-simple__cell">Quantity</th>', '<th class="c-table-simple__cell">Price</th>', '</tr>', '</thead>', '<tbody data-pricing-grid>', '</tbody>', '</table>' ].join(''); let tableBody = volumePricingContainer.querySelector('[data-pricing-grid]'); priceData.data.forEach(function (entry) { const pricingRow = document.createElement('tr'); const quantityCell = document.createElement('td'); const priceCell = document.createElement('td'); pricingRow.classList.add('c-table-simple__row'); quantityCell.classList.add('c-table-simple__cell'); priceCell.classList.add('c-table-simple__cell'); if (entry.low === entry.high) { quantityCell.innerText = entry.low; } else if (entry.high) { quantityCell.innerText = entry.low + ' - ' + entry.high; } else { quantityCell.innerText = entry.low + '+'; } priceCell.innerText = entry.formatted_price; pricingRow.append(quantityCell, priceCell); tableBody.append(pricingRow); }); } else { volumePricingContainer.innerHTML = ''; } };
Comment