PageSourceSearch

https://zuomod.com/wp-content/mu-plugins/widgets/request-swatches/js/request-swatch-modal.js?ver=8e1ee05b

js zuomod.com collected 2026-09-25 18:44:14 UTC 16,453 bytes, 288 lines download raw bytes

1/**
2 * Request Swatch Modal: open/close, form submit, "more fields below" indicator.
3 * Wrapper uses data-swatch-modal-id; config via requestSwatchModal (ajaxUrl, submitAction, toast_duration_ms).
4 */
5(function () {
6    'use strict';
7
8    var config = typeof requestSwatchModal !== 'undefined' ? requestSwatchModal : {};
9    var toast_duration_ms = config.toast_duration_ms || 3000;
10
11    function showToast(message, type) {
12        if (typeof GlobalScripts !== 'undefined' && GlobalScripts.showPopUp) {
13            GlobalScripts.showPopUp(message, type || 'success', toast_duration_ms);
14        }
15    }
16
17    function parseJsonAttr(element, attribute_name, fallback_value) {
18        try {
19            var raw_attribute_value = element.getAttribute(attribute_name);
20            return raw_attribute_value ? JSON.parse(raw_attribute_value) : (fallback_value || {});
21        } catch (parse_error) {
22            return fallback_value || {};
23        }
24    }
25
26    function resolveProductDetailsId(form_element) {
27        var product_id = '';
28        if (typeof window !== 'undefined' && window.__productDetailsData) {
29            product_id = window.__productDetailsData.id || window.__productDetailsData.product_id || '';
30        }
31        if (!product_id && typeof product_details_data !== 'undefined' && product_details_data) {
32            product_id = product_details_data.id || product_details_data.product_id || '';
33        }
34        if (!product_id && form_element) {
35            product_id = form_element.getAttribute('data-product-details') || '';
36        }
37        product_id = product_id == null ? '' : String(product_id).trim();
38        return product_id;
39    }
40
41    function getAdditionalDataFromForm(form_element) {
42        var additional_data = {};
43        try {
44            var raw = form_element.getAttribute('data-additional-data');
45            if (raw) {
46                additional_data = JSON.parse(raw);
47            }
48        } catch (e) {}
49        if (typeof additional_data !== 'object' || additional_data === null) {
50            additional_data = {};
51        }
52        var product_id = resolveProductDetailsId(form_element);
53        if (product_id) {
54            additional_data.product_details = product_id;
55        }
56        return additional_data;
57    }
58
59    function getFieldType(form_element, field_id) {
60        if (!form_element) return null;
61        var wrapper = form_element.querySelector('.form-builder-with-rule[data-name="' + field_id + '"]');
62        if (!wrapper) return null;
63        var attr = parseJsonAttr(wrapper, 'data-attribute', {});
64        return (attr && attr.type) ? attr.type : null;
65    }
66
67    function normalizeValueForPayload(field_id, value, form_element) {
68        var type = getFieldType(form_element, field_id);
69        var arr;
70        if (type === 'select' || type === 'single_select' || type === 'country_single_select' || type === 'state_single_select') {
71            arr = Array.isArray(value) ? value : (value != null && value !== '' ? [value] : []);
72            return { value: arr };
73        }
74        if (type === 'multi_select' || type === 'multiselect') {
75            if (Array.isArray(value)) arr = value;
76            else if (typeof value === 'string') arr = value ? value.split(',').map(function (s) { return s.trim(); }).filter(Boolean) : [];
77            else arr = [];
78            return { value: arr };
79        }
80        return { value: value };
81    }
82
83    function buildRequestSwatchPayload(form_element, form_name) {
84        var additional_data = getAdditionalDataFromForm(form_element);
85        var submitted_values = {};
86        var form_data = typeof window[form_name] !== 'undefined' && window[form_name].data ? window[form_name].data : {};
87        for (var field_id in form_data) {
88            if (form_data.hasOwnProperty(field_id)) {
89                submitted_values[field_id] = normalizeValueForPayload(field_id, form_data[field_id], form_element);
90            }
91        }
92        return { additional_data: additional_data, submitted_values: submitted_values };
93    }
94    if (typeof window !== 'undefined') window.buildRequestSwatchPayload = buildRequestSwatchPayload;
95
96    function clearRequestSwatchForm(formElement, formName) {
97        if (!formElement) return;
98        formName = formName || formElement.getAttribute('data-form-name') || 'request_swatch_modal';
99        window[formName] = window[formName] || { data: {}, errors: {} };
100        window[formName].data = {};
101        window[formName].errors = {};
102        var wrappers = formElement.querySelectorAll('.form-builder
102-with-rule');
103        for (var w = 0; w < wrappers.length; w++) {
104            var fieldId = wrappers[w].getAttribute('data-name');
105            if (!fieldId) continue;
106            var attr = parseJsonAttr(wrappers[w], 'data-attribute', {});
107            var type = (attr && attr.type) ? attr.type : 'text';
108            var emptyVal = (type === 'single_file' || type === 'multi_file') ? [] : '';
109            window[formName].data[fieldId] = emptyVal;
110            try { document.dispatchEvent(new CustomEvent(formName + '_' + fieldId + '_set_value', { detail: { value: emptyVal } })); } catch (e) {}
111        }
112    }
113    if (typeof window !== 'undefined') {
114        window.clearRequestSwatchForm = clearRequestSwatchForm;
115        window.resetRequestSwatchForm = clearRequestSwatchForm;
116    }
117
118    function initRequestSwatchModals() {
119        var button_wrapper_selector = '.request-swatch-button-wrapper[data-swatch-modal-id]';
120        var button_wrapper_elements = document.querySelectorAll(button_wrapper_selector);
121
122        button_wrapper_elements.forEach(function (button_wrapper_element) {
123            var modal_id = button_wrapper_element.getAttribute('data-swatch-modal-id');
124            if (!modal_id) return;
125
126            var open_modal_trigger_button = button_wrapper_element.querySelector('.request-swatch-button');
127            var modal_element = document.getElementById(modal_id);
128            var modal_overlay_element = document.getElementById(modal_id + '-overlay');
129
130            if (!open_modal_trigger_button || !modal_element || !modal_overlay_element) return;
131            if (button_wrapper_element.dataset.requestSwatchInitialized === '1') return;
132            button_wrapper_element.dataset.requestSwatchInitialized = '1';
133
134            function updateMoreFieldsBelowIndicator() {
135                var modal_form_element = modal_element.querySelector('.request-swatch-modal-form');
136                var form_fields_container = modal_form_element ? modal_form_element.querySelector('.request-swatch-modal-form-fields') : null;
137                if (!modal_form_element || !form_fields_container) return;
138                var fields_have_overflow = form_fields_container.scrollHeight > form_fields_container.clientHeight;
139                modal_form_element.classList.toggle('has-scrollable-fields', fields_have_overflow);
140                var scroll_threshold = 8;
141                var at_end = fields_have_overflow && (form_fields_container.scrollTop + form_fields_container.clientHeight >= form_fields_container.scrollHeight - scroll_threshold);
142                modal_form_element.classList.toggle('at-end-of-form', at_end);
143            }
144
145            function openModal() {
146                modal_element.classList.add('open');
147                modal_overlay_element.classList.add('open');
148                document.body.classList.add('request-swatch-modal-open');
149                document.body.style.overflow = 'hidden';
150                setTimeout(updateMoreFieldsBelowIndicator, 100);
151            }
152
153            function closeModal() {
154                var modal_form = modal_element.querySelector('.request-swatch-modal-form');
155                var form_name = modal_form ? (modal_form.getAttribute('data-form-name') || 'request_swatch_modal') : '';
156                if (modal_form && form_name) clearRequestSwatchForm(modal_form, form_name);
157                modal_element.classList.remove('open');
158                modal_overlay_element.classList.remove('open');
159                document.body.classList.remove('request-swatch-modal-open');
160                document.body.style.overflow = '';
161            }
162
163            open_modal_trigger_button.addEventListener('click', openModal);
164            modal_overlay_element.addEventListener('click', function (overlay_click_event) {
165                if (overlay_click_event.target === modal_overlay_element) closeModal();
166            });
167
168            var modal_header_close_button = modal_element.querySelector('.request-swatch-modal-close');
169            if (modal_header_close_button) modal_header_close_button.addEventListener('click', closeModal);
170
171            var modal_footer_cancel_button = modal_element.querySelector('.request-swatch-modal-cancel');
172            if (modal_footer_cancel_button) modal_footer_cancel_button.addEventListener('click', closeModal);
173
174            var submit_spinner_svg = '<span class="request-swatch-modal-submit-spinner" aria-hidden="true"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2" stroke-opacity="0.3"/><path d="M12 2a10 10 0 0 1 10 10" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></span>';
175
176            function setSubmitLoading(loading) {
177                var submit_btn = modal_element.querySelector('.request-swatch-modal-submit');
178                var cancel_btn = modal_element.querySelector('.request-swatch-modal-cancel');
179                if (submit_btn) {
180                    submit_btn.disabled = loading;
181                    if (loading) {
182                        submit_btn.classList.add('request-swatch-modal-submit-loading');
183                        if (!submit_btn.querySelector('.request-swatch-modal-submit-spinner')) {
184                            submit_btn.insertAdjacentHTML('afterbegin', submit_spinner_svg);
185                        }
186                    } else {
187                        submit_btn.classList.remove('request-swatch-modal-submit-loading');
188                        var sp = submit_btn.querySelector('.request-swatch-modal-submit-spinner');
189                        if (sp) sp.remove();
190                    }
191                }
192                if (cancel_btn) cancel_btn.disabled = loading;
193            }
194
195            var modal_form_element = modal_element.querySelector('.request-swatch-modal-form');
196            if (modal_form_element) {
197                modal_form_element.addEventListener('submit', function (submit_event) {
198                    submit_event.preventDefault();
199                    var form_name = modal_form_element.getAttribute('data-form-name') || 'request_swatch_modal';
200                    var form_type = modal_form_element.getAttribute('data-form-type') || 'email_form';
201                    var ajax_submit_url = config.ajaxUrl || null;
202                    var ajax_action_name = config.submitAction || 'request_swatch_form_submit';
203                    if (!ajax_submit_url) {
204                        showToast('Unable to submit request. Please try again.', 'error');
205                        return;
206                    }
207                    if (typeof window.submitFormBuilderNew === 'function') {
208                        window.submitFormBuilderNew(function (fields) {
209                            var additional_data = getAdditionalDataFromForm(modal_form_element);
210                            var submitted_values = {};
211                            for (var field_id in fields) {
212                                if (fields.hasOwnProperty(field_id)) {
213                                    submitted_values[field_id] = normalizeValueForPayload(field_id, fields[field_id], modal_form_element);
214                                }
215                            }
216                            var submission_payload = { additional_data: additional_data, submitted_values: submitted_values };
217                            setSubmitLoading(true);
218                            var form_data_for_submit = new FormData();
219                            form_data_for_submit.append('action', ajax_action_name);
220                            form_data_for_submit.append('form_type', form_type);
221                            form_data_for_submit.append('payload', JSON.stringify(submission_payload));
222                            fetch(ajax_submit_url, { method: 'POST', body: form_data_for_submit })
223                                .then(function (res) {
224                                    return res.json().catch(function () { return null; }).then(function (json) {
225                                        if (res.ok && json && json.success) {
226                                            showToast('Swatch request submitted successfully.', 'success');
227                                            clearRequestSwatchForm(modal_form_element, form_name);
228                                            closeModal();
229                                        } else {
230                                            var msg = (json && json.data && json.data.message) ? json.data.message : 'Unable to submit request. Please try again.';
231                                            showToast(msg, 'error');
232                                        }
233                                    });
234                                })
235                                .catch(function () {
236                                    showToast('Something went wrong. Please try again.', 'error');
237                                })
238                                .finally(function () {
239                                    setSubmitLoading(false);
240                                });
241                        }, form_name).then(function (didSubmit) {
242                            if (!didSubmit) showToast('Please fill in all required fields.', 'error');
243                        });
244                    } else {
245                        var submission_payload = buildRequestSwatchPayload(modal_form_element, form_name);
246                        setSubmitLoading(true);
247                        var form_data_for_submit = new FormData();
248                        form_data_for_submit.append('action', ajax_action_name);
249                        form_data_for_submit.append('form_type', modal_form_element.getAttribute('data-form-type') || 'email_form');
250                        form_data_for_submit.append('payload', JSON.stringify(submission_payload));
251                        fetch(ajax_submit_url, { method: 'POST', body: form_data_for_submit })
252                            .then(function (res) {
253                                return res.json().catch(function () { return null; }).then(function (json) {
254                                    if (res.ok && json && json.success) {
255                                        showToast('Swatch request submitted successfully.', 'success');
256                                        clearRequestSwatchForm(modal_form_element, form_name);
257                                        closeModal();
258                                    } else {
259                                        var msg = (json && json.data && json.data.message) ? json.data.message : 'Unable to submit request. Please try again.';
260                                        showToast(msg, 'error');
261                                    }
262                                });
263                            })
264                            .catch(function () {
265                                showToast('Something went wrong. Please try again.', 'error');
266                            })
267                            .finally(function () {
268                                setSubmitLoading(false);
269                            });
270                    }
271                });
272                var form_fields_container = modal_form_element.querySelector('.request-swatch-modal-form-fields');
273                if (form_fields_container) form_fields_container.addEventListener('scroll', updateMoreFieldsBelowIndicator);
274            }
275
276            updateMoreFieldsBelowIndicator();
277            document.addEventListener('keydown', function (keyboard_event) {
278                if (keyboard_event.key === 'Escape' && modal_element.classList.contains('open')) closeModal();
279            });
280        });
281    }
282
283    if (document.readyState === 'loading') {
284        document.addEventListener('DOMContentLoaded', initRequestSwatchModals);
285    } else {
286        initRequestSwatchModals();
287    }
288})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.