PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.78
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.78
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / widgets / Woo_Product_Variations / script.js

script.js in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.78, at includes/widgets/Woo_Product_Variations/script.js

166 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Woo Product Variations widget behavior.
3 *
4 * Enhances variation selects with swatches.
5 */
6 (function ($) {
7 "use strict";
8
9 const INIT_FLAG = "kaWooVariationsInit";
10
11 const initVariations = (wrap) => {
12 if (!wrap || !wrap.dataset) return;
13 if (wrap.dataset[INIT_FLAG] === "1") return;
14 wrap.dataset[INIT_FLAG] = "1";
15
16 const form = wrap.querySelector('form.variations_form');
17 if (!form) return;
18
19 if (wrap.dataset.swatches !== 'yes') return;
20
21 let map = {};
22 try {
23 map = wrap.dataset.swatchesMap ? JSON.parse(wrap.dataset.swatchesMap) : {};
24 } catch (e) {
25 map = {};
26 }
27
28 const unavailableBehavior = map.unavailable || 'disable';
29 const showSelected = map.show_selected === 'yes';
30 const shape = map.shape || 'square';
31 const attrMap = (map.map) || {};
32 const source = map.source || 'auto';
33
34 const selects = form.querySelectorAll('select');
35 const updateCallbacks = [];
36 const runAll = () => updateCallbacks.forEach((cb) => cb());
37
38 selects.forEach((select) => {
39 const attrName = select.name;
40 const swatchesInfo = attrMap[attrName];
41 if (!swatchesInfo) {
42 return;
43 }
44
45 const container = document.createElement('div');
46 container.className = 'ka-woo-variations__swatches';
47
48 const selectedText = document.createElement('div');
49 selectedText.className = 'ka-woo-variations__selected';
50
51 const options = Array.from(select.options).filter((opt) => opt.value !== '');
52 options.forEach((opt) => {
53 const btn = document.createElement('button');
54 btn.type = 'button';
55 btn.className = 'ka-woo-variations__swatch';
56 if (shape === 'round') {
57 btn.classList.add('ka-woo-variations__swatch--round');
58 }
59 btn.dataset.value = opt.value;
60
61 const info = swatchesInfo[opt.value] || {};
62
63 if (source === 'text') {
64 const span = document.createElement('span');
65 span.className = 'ka-woo-variations__swatch-text';
66 span.textContent = info.label || opt.text;
67 btn.appendChild(span);
68 } else if (info.image) {
69 const img = document.createElement('img');
70 img.src = info.image;
71 img.alt = info.label || opt.text;
72 img.className = 'ka-woo-variations__swatch-img';
73 btn.appendChild(img);
74 } else if (info.color) {
75 const span = document.createElement('span');
76 span.className = 'ka-woo-variations__swatch-color';
77 span.style.background = info.color;
78 btn.appendChild(span);
79 } else {
80 const span = document.createElement('span');
81 span.className = 'ka-woo-variations__swatch-text';
82 span.textContent = info.label || opt.text;
83 btn.appendChild(span);
84 }
85
86 btn.addEventListener('click', () => {
87 select.value = opt.value;
88 select.dispatchEvent(new Event('change', { bubbles: true }));
89 if (window.jQuery) {
90 window.jQuery(select).trigger('change');
91 }
92 runAll();
93 });
94
95 container.appendChild(btn);
96 });
97
98 select.style.display = 'none';
99 select.insertAdjacentElement('afterend', container);
100 if (showSelected) {
101 container.insertAdjacentElement('afterend', selectedText);
102 }
103
104 const updateStates = () => {
105 const current = select.value;
106 Array.from(container.children).forEach((btn) => {
107 const val = btn.dataset.value;
108 const opt = select.querySelector(`option[value="${val}"]`);
109 const disabled = opt && opt.disabled;
110 btn.classList.toggle('is-active', current === val);
111 btn.classList.toggle('is-disabled', !!disabled);
112 if (disabled && unavailableBehavior === 'hide') {
113 btn.style.display = 'none';
114 } else {
115 btn.style.display = '';
116 }
117 });
118 if (showSelected) {
119 const label = (swatchesInfo[current] && swatchesInfo[current].label) || current || '';
120 const prefix = select.getAttribute('aria-label') || '';
121 selectedText.textContent = label ? `${prefix}: ${label}` : '';
122 }
123 };
124
125 select.addEventListener('change', runAll);
126 updateCallbacks.push(updateStates);
127 });
128
129 runAll();
130
131 // Sync with WooCommerce variation script events.
132 if (window.jQuery) {
133 const $form = window.jQuery(form);
134 $form.on('woocommerce_update_variation_values woocommerce_variation_has_changed reset_data found_variation hide_variation', runAll);
135 const resetBtn = form.querySelector('.reset_variations');
136 if (resetBtn) {
137 resetBtn.addEventListener('click', () => {
138 setTimeout(runAll, 50);
139 });
140 }
141 }
142 };
143
144 const initAll = (root) => {
145 const ctx = root && root.querySelectorAll ? root : document;
146 ctx.querySelectorAll(".ka-woo-variations").forEach(initVariations);
147 };
148
149 document.addEventListener("DOMContentLoaded", () => initAll(document));
150
151 $(window).on("elementor/frontend/init", function () {
152 elementorFrontend.hooks.addAction(
153 "frontend/element_ready/woo_product_variations.default",
154 function ($scope) {
155 initAll($scope && $scope[0] ? $scope[0] : document);
156 }
157 );
158 });
159 })(jQuery);
160
161
162
163
164
165
166