PageSourceSearch

https://www.esign.pl/forms.js

js esign.pl collected 2026-10-08 07:25:22 UTC 11,779 bytes, 321 lines download raw bytes

1/*
2 * eSIGN: wspolna obsluga formularzy Formspark.
3 *
4 * Konfiguracja po utworzeniu konta:
5 * - w kazdym formularzu uzupelnij tylko data-formspark-form-id;
6 * - data-turnstile-site-key uzupelnij po skonfigurowaniu Turnstile;
7 * - sekret Turnstile zostaje w panelu Formspark. Nigdy nie trafia do tego pliku.
8 */
9(function () {
10    'use strict';
11
12    var FORM_SELECTOR = '[data-esign-lead-form]';
13    var TURNSTILE_SCRIPT_URL = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit';
14    var EMAIL_NOTIFICATION_SENDER = 'Zapytanie ze strony WWW';
15    var turnstileLoader;
16
17    function currentLanguageIsEnglish() {
18        return !!(document.body && document.body.classList.contains('lang-en'));
19    }
20
21    function getCopy(form, kind) {
22        var language = currentLanguageIsEnglish() ? 'en' : 'pl';
23        var attribute = 'data-' + kind + '-' + language;
24        return form.getAttribute(attribute) || form.getAttribute('data-' + kind + '-pl') || '';
25    }
26
27    function getEndpoint(form) {
28        var formId = (form.getAttribute('data-formspark-form-id') || '').trim();
29        return formId ? 'https://submit-form.com/' + encodeURIComponent(formId) : '';
30    }
31
32    function getStatus(form) {
33        return form.parentElement && form.parentElement.querySelector('.form-status-message');
34    }
35
36    function showStatus(form, state, message) {
37        var status = getStatus(form);
38        if (!status) return;
39
40        status.textContent = message;
41        status.dataset.state = state;
42        if (state === 'error') {
43            status.style.background = '#fef2f2';
44            status.style.color = '#991b1b';
45            status.style.border = '1px solid #fecaca';
46        } else {
47            status.style.background = '';
48            status.style.color = '';
49            status.style.border = '';
50        }
51        status.classList.add('visible');
52    }
53
54    function clearStatus(form) {
55        var status = getStatus(form);
56        if (!status) return;
57
58        status.classList.remove('visible');
59        delete status.dataset.state;
60        status.style.background = '';
61        status.style.color = '';
62        status.style.border = '';
63        status.textContent = '';
64    }
65
66    function setSubmitting(form, isSubmitting) {
67        var button = form.querySelector('button[type="submit"]');
68        if (!button) return;
69
70        if (!button.dataset.originalLabel) {
71            button.dataset.originalLabel = button.innerHTML;
72        }
73
74        button.disabled = isSubmitting;
75        button.setAttribute('aria-busy', isSubmitting ? 'true' : 'false');
76        button.innerHTML = isSubmitting ? getCopy(form, 'sending') : button.dataset.originalLabel;
77    }
78
79    function validateForm(form) {
80        var name = form.querySelector('[name="imie"]');
81        var phone = form.querySelector('[name="telefon"]');
82        var problem = form.querySelector('[name="problem"]');
83        var email = form.querySelector('[name="email"]');
84        var marketingConsent = form.querySelector('[name="zgoda_marketingowa"]');
85
86        [name, phone, problem, email].forEach(function (field) {
87            if (field) field.setCustomValidity('');
88        });
89
90        if (name && name.value.trim().length < 2) {
91            name.setCustomValidity(getCopy(form, 'name-error'));
92        }
93
94        if (phone) {
95            var digits = phone.value.replace(/\D/g, '');
96            if (digits.length < 7 || digits.length > 15) {
97                phone.setCustomValidity(getCopy(form, 'phone-error'));
98            }
99        }
100
101        if (problem && problem.value.trim().length < 3) {
102            problem.setCustomValidity(getCopy(form, 'problem-error'));
103        }
104
105        if (marketingConsent && marketingConsent.checked && email && !email.validity.valid) {
106            email.setCustomValidity(getCopy(form, 'marketing-email-error'));
107        }
108
109        return form.checkValidity();
110    }
111
112    function syncMarketingEmailRequirement(form) {
113        var marketingConsent = form.querySelector('[name="zgoda_marketingowa"]');
114        var email = form.querySelector('[name="email"]');
115        var emailAlwaysRequired = form.getAttribute('data-email-required-always') === 'true';
116
117        if (!marketingConsent || !email) return;
118
119        email.required = emailAlwaysRequired || marketingConsent.checked;
120        email.setAttribute('aria-required', email.required ? 'true' : 'false');
121    }
122
123    function getEmailNotificationSettings(form) {
124        var service = form.getAttribute('data-form-name') || 'Usługa';
125        var name = form.querySelector('[name="imie"]');
126        var clientName = name ? name.value.trim() : '';
127
128        if (service === 'Odnowienia podpisu') service = 'Odnowienie podpisu';
129        return {
130            from: EMAIL_NOTIFICATION_SENDER,
131            subject: service + ' | ' + clientName
132        };
133    }
134
135    function formatNotificationPhone(phone, form) {
136        var original = phone ? String(phone).trim() : '';
137        var digits = original.replace(/\D/g, '');
138        var isForeignForm = form.getAttribute('data-form-name') === 'Podpis dla obcokrajowca';
139        var polishNumber = '';
140
141        if (/^0048\d{9}$/.test(digits)) {
142            polishNumber = digits.slice(4);
143        } else if (/^48\d{9}$/.test(digits)) {
144            polishNumber = digits.slice(2);
145        } else if (!isForeignForm && /^\d{9}$/.test(digits)) {
146            polishNumber = digits;
147        }
148
149        if (!polishNumber) return original;
150
151        return '+48 ' + polishNumber.replace(/(\d{3})(?=\d)/g, '$1 ').trim();
152    }
153
154    function formPayload(form) {
155        var payload = {};
156        var data = new FormData(form);
157        var marketingConsent = form.querySelector('[name="zgoda_marketingowa"]');
158        var submittedAt = new Date().toISOString();
159
160        data.forEach(function (value, key) {
161            payload[key] = typeof value === 'string' ? value.trim() : value;
162        });
163
164        payload.formularz = form.getAttribute('data-form-name') || 'Formularz eSIGN';
165        payload.strona = window.location.pathname;
166        payload.strona_zrodlowa = window.location.pathname;
167        payload.data_wyslania = submittedAt;
168        payload.zgoda_marketingowa = marketingConsent ? (marketingConsent.checked ? 'tak' : 'nie') : 'nie_dotyczy';
169        payload.data_zgody_marketingowej = marketingConsent && marketingConsent.checked ? submittedAt : 'nie_dotyczy';
170        payload.wersja_tresci_zgody = 'marketing-v1-2026-08-12';
171        payload.telefon_powiadomienie = formatNotificationPhone(payload.telefon, form);
172        payload._email = getEmailNotificationSettings(form);
173        return payload;
174    }
175
176    function trackSavedLead(form) {
177        var detail = {
178            formName: form.getAttribute('data-form-name') || 'Formularz eSIGN',
179            sourcePath: window.location.pathname
180        };
181
182        window.dispatchEvent(new CustomEvent('esign:lead-saved', { detail: detail }));
183    }
184
185    function loadTurnstile() {
186        if (turnstileLoader) return turnstileLoader;
187
188        turnstileLoader = new Promise(function (resolve, reject) {
189            var existing = document.getElementById('esign-turnstile-script');
190            if (existing) {
191                existing.addEventListener('load', function () { resolve(window.turnstile); }, { once: true });
192                existing.addEventListener('error', reject, { once: true });
193                return;
194            }
195
196            var script = document.createElement('script');
197            script.id = 'esign-turnstile-script';
198            script.src = TURNSTILE_SCRIPT_URL;
199            script.async = true;
200            script.onload = function () { resolve(window.turnstile); };
201            script.onerror = reject;
202            document.head.appendChild(script);
203        });
204
205        return turnstileLoader;
206    }
207
208    function prepareTurnstile(form) {
209        var siteKey = (form.getAttribute('data-turnstile-site-key') || '').trim();
210        var mount = form.querySelector('[data-turnstile-widget]');
211        var responseField = form.querySelector('[name="cf-turnstile-response"]');
212
213        if (!siteKey || !mount || !responseField) return;
214
215        mount.hidden = false;
216        loadTurnstile().then(function (turnstile) {
217            if (!turnstile || mount.dataset.rendered === 'true') return;
218
219            mount.dataset.rendered = 'true';
220            mount.dataset.widgetId = turnstile.render(mount, {
221                sitekey: siteKey,
222                callback: function (token) { responseField.value = token; },
223                'expired-callback': function () { responseField.value = ''; },
224                'error-callback': function () { responseField.value = ''; }
225            });
226        }).catch(function () {
227            showStatus(form, 'error', getCopy(form, 'turnstile-error'));
228        });
229    }
230
231    function resetTurnstile(form) {
232        var mount = form.querySelector('[data-turnstile-widget]');
233        if (mount && mount.dataset.widgetId && window.turnstile) {
234            window.turnstile.reset(mount.dataset.widgetId);
235        }
236    }
237
238    async function handleSubmit(event) {
239        event.preventDefault();
240
241        var form = event.currentTarget;
242        if (form.dataset.submitting === 'true') return;
243
244        if (!validateForm(form)) {
245            form.reportValidity();
246            return;
247        }
248
249        var endpoint = getEndpoint(form);
250        if (!endpoint) {
251            showStatus(form, 'error', getCopy(form, 'config-error'));
252            return;
253        }
254
255        var honeypot = form.querySelector('[name="_honeypot"]');
256        if (honeypot && honeypot.value.trim() !== '') {
257            showStatus(form, 'error', getCopy(form, 'generic-error'));
258            return;
259        }
260
261        var turnstileField = form.querySelector('[name="cf-turnstile-response"]');
262        if ((form.getAttribute('data-turnstile-site-key') || '').trim() && (!turnstileField || !turnstileField.value)) {
263            showStatus(form, 'error', getCopy(form, 'turnstile-required'));
264            return;
265        }
266
267        form.dataset.submitting = 'true';
268        clearStatus(form);
269        setSubmitting(form, true);
270
271        try {
272            var response = await fetch(endpoint, {
273                method: 'POST',
274                headers: {
275                    'Content-Type': 'application/json',
276                    'Accept': 'application/json'
277                },
278                body: JSON.stringify(formPayload(form)),
279                credentials: 'omit'
280            });
281
282            if (!response.ok) {
283                throw new Error('HTTP ' + response.status);
284            }
285
286            await response.json();
287            form.reset();
288            resetTurnstile(form);
289            showStatus(form, 'success', getCopy(form, 'success'));
290            trackSavedLead(form);
291        } catch (error) {
292            showStatus(form, 'error', getCopy(form, 'generic-error'));
293        } finally {
294            delete form.dataset.submitting;
295            setSubmitting(form, false);
296        }
297    }
298
299    function prepareForm(form) {
300        form.addEventListener('submit', handleSubmit);
301        form.addEventListener('input', function () { clearStatus(form); });
302        form.addEventListener('change', function (event) {
303            if (event.target && event.target.name === 'zgoda_marketingowa') {
304                syncMarketingEmailRequirement(form);
305                clearStatus(form);
306            }
307        });
308        syncMarketingEmailRequirement(form);
309        prepareTurnstile(form);
310    }
311
312    function initialize() {
313        document.querySelectorAll(FORM_SELECTOR).forEach(prepareForm);
314    }
315
316    if (document.readyState === 'loading') {
317        document.addEventListener('DOMContentLoaded', initialize);
318    } else {
319        initialize();
320    }
321}());

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.