PageSourceSearch

https://hanston.ru/wp-content/themes/jirs-groovy-site/js/ds-forms.js?ver=1782728998

js hanston.ru collected 2026-10-08 11:22:25 UTC 11,472 bytes, 376 lines download raw bytes

1(function (window, document, $) {
2    'use strict';
3
4    var config = window.DSFormsConfig || {};
5
6    var mailerUrl = config.mailerUrl || '/wp-content/themes/jirs-groovy-site/mailer.php';
7    var defaultRedirect = config.defaultRedirect || '/spasibo';
8    var debug = !!config.debug;
9
10    var fieldNames = config.fieldNames || {};
11    var F_FORM = fieldNames.form || 'Форма';
12    var F_QUERY = fieldNames.query || 'Запрос';
13    var F_TITLE = fieldNames.title || 'Заголовок';
14    var F_PAGE = fieldNames.page || 'Страница';
15
16    var lockedForms = new WeakMap();
17
18    function log() {
19        if (!debug || !window.console) return;
20        console.log.apply(console, arguments);
21    }
22
23    function shouldHandleForm(form) {
24        if (!form || form.nodeType !== 1) return false;
25
26        if (form.matches('#search_filter_ajax')) return false;
27        if (form.matches('.search_form')) return false;
28        if (form.hasAttribute('data-ds-no-mailer')) return false;
29
30        if (form.closest('.w-form')) return true;
31        if (form.hasAttribute('data-ds-mailer')) return true;
32        if (form.hasAttribute('data-name') && form.hasAttribute('data-redirect')) return true;
33
34        return false;
35    }
36
37    function getFormTitle(form) {
38        return (
39            form.getAttribute('data-name') ||
40            form.getAttribute('name') ||
41            form.getAttribute('id') ||
42            'Форма сайта'
43        );
44    }
45
46    function setHidden(form, name, value) {
47        var input = form.querySelector('input[type="hidden"][name="' + cssEscape(name) + '"]');
48
49        if (!input) {
50            input = document.createElement('input');
51            input.type = 'hidden';
52            input.name = name;
53            input.setAttribute('data-name', name);
54            form.insertBefore(input, form.firstChild);
55        }
56
57        input.value = value == null ? '' : String(value);
58    }
59
60    function cssEscape(value) {
61        if (window.CSS && typeof window.CSS.escape === 'function') {
62            return window.CSS.escape(value);
63        }
64
65        return String(value).replace(/["\\]/g, '\\$&');
66    }
67
68    function normalizeFieldNames(form) {
69        var elements = form.querySelectorAll('input, select, textarea');
70
71        elements.forEach(function (el) {
72            var dataName = el.getAttribute('data-name');
73
74            if (dataName) {
75                el.setAttribute('name', dataName);
76            }
77        });
78    }
79
80    function fillServiceFields(form) {
81        var formTitle = getFormTitle(form);
82
83        setHidden(form, F_FORM, formTitle);
84        setHidden(form, F_QUERY, window.location.search || '');
85        setHidden(form, F_TITLE, document.title || '');
86        setHidden(form, F_PAGE, window.location.origin + window.location.pathname);
87
88        // Алиасы для твоих текущих хуков в custom_functions.php.
89        // Если переводчик вернул Form/Query/Title/Page, хуки всё равно увидят русские ключи.
90        if (F_FORM !== 'Форма') setHidden(form, 'Форма', formTitle);
91        if (F_QUERY !== 'Запрос') setHidden(form, 'Запрос', window.location.search || '');
92        if (F_TITLE !== 'Заголовок') setHidden(form, 'Заголовок', document.title || '');
93        if (F_PAGE !== 'Страница') setHidden(form, 'Страница', window.location.origin + window.location.pathname);
94    }
95
96    function fillRequiredFields(form) {
97        var names = [];
98
99        form.querySelectorAll('[required]').forEach(function (el) {
100            var name = el.getAttribute('name');
101
102            if (name && names.indexOf(name) === -1) {
103                names.push(name);
104            }
105        });
106
107        setHidden(form, 'required_fields', names.join(','));
108    }
109
110    function getPhoneField(form) {
111        return (
112            form.querySelector('[name="Телефон"]') ||
113            form.querySelector('[data-name="Телефон"]') ||
114            form.querySelector('.input-phone') ||
115            form.querySelector('.is--phone-mask') ||
116            form.querySelector('input[type="tel"]')
117        );
118    }
119
120    function getEmailField(form) {
121        return (
122            form.querySelector('[name="Email"]') ||
123            form.querySelector('[data-name="Email"]') ||
124            form.querySelector('.input-email') ||
125            form.querySelector('input[type="email"]')
126        );
127    }
128
129    function validatePhone(value) {
130        var digits = String(value || '').replace(/\D/g, '');
131        //const patternPhone = /^[-\w.]+@([A-z0-9][-A-z0-9]+\.)+[A-z]{2,4}$/;
132       
133
134        if (digits.length === 10) return true;
135        if (digits.length === 11 && (digits.charAt(0) === '7' || digits.charAt(0) === '8')) return true;
136
137        return false;
138    }
139
140    function validateEmail(value) {
141        value = String(value || '').trim();
142
143        if (value === '') return true;
144
145        return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
146    }
147
148    function validateForm(form) {
149        normalizeFieldNames(form);
150
151        if (typeof form.reportValidity === 'function' && !form.checkValidity()) {
152            form.reportValidity();
153            return false;
154        }
155
156        var phone = getPhoneField(form);
157        if (phone && phone.value.trim() !== '' && !validatePhone(phone.value)) {
158            alert('Проверь телефон. Нужен формат +7 (999) 999-99-99.');
159            phone.focus();
160            return false;
161        }
162
163        var email = getEmailField(form);
164        if (email && !validateEmail(email.value)) {
165            alert('Проверь e-mail.');
166            email.focus();
167            return false;
168        }
169
170        return true;
171    }
172
173    function getSubmitButton(form) {
174        return $(form).find('[type="submit"]').first();
175    }
176
177    function setSending(form, sending) {
178        var $form = $(form);
179        var $submit = getSubmitButton(form);
180
181        $form.toggleClass('is-sending', sending);
182
183        if (!$submit.length) return;
184
185        if (sending) {
186            if (!$submit.data('ds-label')) {
187                $submit.data('ds-label', $submit.is('input') ? $submit.val() : $submit.text());
188            }
189
190            var waitText = $submit.attr('data-wait') || 'Отправка...';
191
192            $submit.prop('disabled', true);
193
194            if ($submit.is('input')) {
195                $submit.val(waitText);
196            } else {
197                $submit.text(waitText);
198            }
199        } else {
200            var label = $submit.data('ds-label');
201
202            $submit.prop('disabled', false);
203
204            if (label) {
205                if ($submit.is('input')) {
206                    $submit.val(label);
207                } else {
208                    $submit.text(label);
209                }
210            }
211        }
212    }
213
214    function getFormWrap(form) {
215        return $(form).closest('.w-form');
216    }
217
218    function showFormState(form, isSuccess, message) {
219        var $wrap = getFormWrap(form);
220        var $done = $wrap.find('.w-form-done').first();
221        var $fail = $wrap.find('.w-form-fail').first();
222
223        if (!$wrap.length) return;
224
225        if (isSuccess) {
226            $fail.hide();
227
228            if (message && $done.length) {
229                $done.html('<div>' + message + '</div>');
230            }
231
232            $done.show();
233        } else {
234            $done.hide();
235
236            if (message && $fail.length) {
237                $fail.html('<div>' + message + '</div>');
238            }
239
240            $fail.show();
241        }
242    }
243
244    function parseResponse(response) {
245        if (typeof response === 'object') {
246            return response;
247        }
248
249        if (response === 'ERROR_RECAPTCHA') {
250            return {
251                status: 'error',
252                error: 'ERROR_RECAPTCHA',
253                error_msg: 'Подтвердите, что вы не робот.'
254            };
255        }
256
257        try {
258            return JSON.parse(response);
259        } catch (e) {
260            return {
261                status: 'error',
262                error: 'BAD_JSON',
263                error_msg: 'Ошибка отправки формы.',
264                raw: response
265            };
266        }
267    }
268
269    function redirectAfterSuccess(form, result) {
270        var redirect = form.getAttribute('data-redirect') || form.getAttribute('redirect') || '';
271
272        if (!redirect && result.redirect && result.redirect !== '/-') {
273            redirect = result.redirect;
274        }
275
276        if (!redirect) {
277            redirect = defaultRedirect;
278        }
279
280        if (redirect) {
281            if (result.redirect_new_tab) {
282                window.open(redirect);
283            } else {
284                window.location.href = redirect;
285            }
286        }
287    }
288
289    function sendForm(form) {
290        if (lockedForms.get(form)) return;
291
292        normalizeFieldNames(form);
293
294        if (!validateForm(form)) return;
295
296        fillServiceFields(form);
297        fillRequiredFields(form);
298
299        var formData = new FormData(form);
300
301        lockedForms.set(form, true);
302        setSending(form, true);
303
304        log('[ds-forms] send to mailer', mailerUrl, form);
305
306        $.ajax({
307            url: mailerUrl,
308            type: 'POST',
309            data: formData,
310            processData: false,
311            contentType: false
312        }).done(function (response) {
313            var result = parseResponse(response);
314
315            log('[ds-forms] response', result);
316
317            if (typeof window.wtw_after_send_from === 'function') {
318                window.wtw_after_send_from(response);
319            }
320
321            if (result.status === 'success') {
322                showFormState(form, true, result.success_msg || '');
323                form.reset();
324                redirectAfterSuccess(form, result);
325                return;
326            }
327
328            if (result.error === 'ERROR_REQUIRED') {
329                showFormState(form, false, 'Заполните обязательные поля.');
330            } else {
331                showFormState(form, false, result.error_msg || 'Ошибка отправки формы.');
332            }
333        }).fail(function (xhr) {
334            log('[ds-forms] ajax fail', xhr);
335
336            showFormState(form, false, 'Ошибка отправки формы.');
337        }).always(function () {
338            lockedForms.delete(form);
339            setSending(form, false);
340        });
341    }
342
343    function onSubmit(event) {
344        var form = event.target;
345
346        if (!shouldHandleForm(form)) return;
347
348        event.preventDefault();
349        event.stopPropagation();
350
351        if (typeof event.stopImmediatePropagation === 'function') {
352            event.stopImmediatePropagation();
353        }
354
355        sendForm(form);
356    }
357
358    document.addEventListener('submit', onSubmit, true);
359
360    document.addEventListener('DOMContentLoaded', function () {
361        document.querySelectorAll('form').forEach(function (form) {
362            if (!shouldHandleForm(form)) return;
363
364            normalizeFieldNames(form);
365
366            if (!form.getAttribute('method') || form.getAttribute('method').toLowerCase() === 'get') {
367                form.setAttribute('method', 'post');
368            }
369
370            if (!form.getAttribute('action') || form.getAttribute('action') === window.location.href) {
371                form.setAttribute('action', mailerUrl);
372            }
373        });
374    });
375
376})(window, document, jQuery);

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.