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_Cart_Table / 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_Cart_Table/script.js

172 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Woo Cart Table widget behavior.
3 *
4 * Handles cart quantity updates and item removal via AJAX.
5 * Exposes a global initializer for other cart-related widgets.
6 */
7 (function ($) {
8 "use strict";
9
10 const FLAG = "kaCartTableInit";
11
12 const KACartTable = window.KACartTable || (() => {
13 const getKeyFromInput = (input) => {
14 const name = input.getAttribute('name') || '';
15 const match = name.match(/cart\[(.+?)\]\[qty\]/);
16 return match ? match[1] : '';
17 };
18
19 const getKeyFromRemove = (link) => {
20 const href = link.getAttribute('href') || '';
21 try {
22 const url = new URL(href, window.location.href);
23 return url.searchParams.get('remove_item') || '';
24 } catch (e) {
25 return '';
26 }
27 };
28
29 const setNotices = (wrapper, notices) => {
30 let container = document.querySelector('.woocommerce-notices-wrapper');
31 if (!container) {
32 container = document.createElement('div');
33 container.className = 'woocommerce-notices-wrapper';
34 wrapper.prepend(container);
35 }
36 container.innerHTML = notices || '';
37 };
38
39 const applyFragments = (wrapper, data) => {
40 if (data.cart_html) {
41 wrapper.innerHTML = data.cart_html;
42 }
43
44 // Allow re-binding after HTML replacement.
45 if (wrapper && wrapper.dataset) {
46 delete wrapper.dataset[FLAG];
47 }
48
49 if (data.totals_html !== undefined) {
50 document.querySelectorAll('.ka-woo-cart-totals').forEach((totals) => {
51 totals.innerHTML = data.totals_html || '';
52 });
53 }
54
55 if (data.cross_sells_html !== undefined) {
56 document.querySelectorAll('.ka-woo-cart-cross-sells').forEach((cross) => {
57 cross.innerHTML = data.cross_sells_html || '';
58 });
59 if (window.KACartCrossSells && typeof window.KACartCrossSells.init === "function") {
60 window.KACartCrossSells.init();
61 }
62 }
63
64 setNotices(wrapper, data.notices || '');
65 initWrapper(wrapper);
66 };
67
68 const request = (wrapper, payload) => {
69 const ajaxUrl = wrapper.dataset.ajaxUrl;
70 const nonce = wrapper.dataset.nonce;
71 if (!ajaxUrl || !nonce) {
72 return Promise.resolve();
73 }
74
75 const body = new URLSearchParams();
76 body.append('action', 'ka_cart_update');
77 body.append('nonce', nonce);
78 Object.entries(payload).forEach(([k, v]) => body.append(k, v));
79
80 wrapper.classList.add('loading');
81
82 return fetch(ajaxUrl, {
83 method: 'POST',
84 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
85 body: body.toString(),
86 credentials: 'same-origin',
87 })
88 .then((res) => res.json())
89 .then((res) => {
90 if (res && res.success) {
91 applyFragments(wrapper, res.data || {});
92 }
93 })
94 .catch(() => {})
95 .finally(() => wrapper.classList.remove('loading'));
96 };
97
98 const bindEvents = (wrapper) => {
99 if (!wrapper || !wrapper.dataset) return;
100 if (wrapper.dataset[FLAG] === "1") return;
101 wrapper.dataset[FLAG] = "1";
102
103 const form = wrapper.querySelector('.woocommerce-cart-form');
104 if (!form) return;
105
106 form.addEventListener('submit', (e) => {
107 e.preventDefault();
108 });
109
110 form.addEventListener('change', (e) => {
111 const target = e.target;
112 if (!(target instanceof HTMLInputElement)) return;
113 if (target.name && target.name.startsWith('cart[')) {
114 const key = getKeyFromInput(target);
115 if (key) {
116 request(wrapper, { op: 'qty', cart_item_key: key, qty: target.value });
117 }
118 }
119 });
120
121 form.addEventListener('click', (e) => {
122 const target = e.target;
123 if (!(target instanceof HTMLElement)) return;
124 if (target.closest('a.remove')) {
125 e.preventDefault();
126 const link = target.closest('a.remove');
127 const key = getKeyFromRemove(link);
128 if (key) {
129 request(wrapper, { op: 'remove', cart_item_key: key });
130 }
131 }
132 });
133 };
134
135 const initWrapper = (wrapper) => {
136 bindEvents(wrapper);
137 };
138
139 const init = (root) => {
140 const ctx = root && root.querySelectorAll ? root : document;
141 ctx.querySelectorAll('.ka-cart-table').forEach((wrapper) => {
142 initWrapper(wrapper);
143 });
144 };
145
146 return { init };
147 })();
148
149 window.KACartTable = KACartTable;
150
151 const initInScope = ($scope) => {
152 const root = $scope && $scope[0] ? $scope[0] : document;
153 KACartTable.init(root);
154 };
155
156 document.addEventListener("DOMContentLoaded", () => KACartTable.init(document));
157
158 $(window).on("elementor/frontend/init", function () {
159 elementorFrontend.hooks.addAction(
160 "frontend/element_ready/woo_cart_table.default",
161 function ($scope) {
162 initInScope($scope);
163 }
164 );
165 });
166 })(jQuery);
167
168
169
170
171
172