1document.addEventListener('DOMContentLoaded', function () { 2 // reCAPTCHA клÑÑ (v3). ÐамениÑе на Ñвой: 3 const siteKey = '6LfsZr4qAAAAAKkDvpFQaP5qsRrp4nJOENhnpX6l'; 4 5 function showFormMessage(form, message, isSuccess = false) { 6 let resultBlock = form.querySelector('.cf-result'); 7 if (!resultBlock) { 8 resultBlock = document.createElement('div'); 9 resultBlock.classList.add('cf-result'); 10 form.appendChild(resultBlock); 11 } 12 resultBlock.innerHTML = ''; 13 14 const msgDiv = document.createElement('div'); 15 msgDiv.classList.add('cf-notification'); 16 msgDiv.classList.add(isSuccess ? 'cf-notification--success' : 'cf-notification--error'); 17 msgDiv.textContent = message; 18 19 resultBlock.appendChild(msgDiv); 20 } 21 22 function getCookie(name) { 23 const matches = document.cookie.match(new RegExp( 24 "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\+^])/g, '\\$1') + "=([^;]*)" 25 )); 26 return matches ? decodeURIComponent(matches[1]) : ""; 27 } 28 29 function getUrlParams() { 30 const params = {}; 31 const query = window.location.search.substring(1); 32 if (!query) return params; 33 query.split('&').forEach(part => { 34 const [key, val] = part.split('='); 35 if (key) params[decodeURIComponent(key)] = decodeURIComponent(val || ''); 36 }); 37 return params; 38 } 39 40 function saveUTMToSessionStorage(params) { 41 ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'].forEach(param => { 42 if (params[param]) { 43 sessionStorage.setItem(param, params[param]); 44 } 45 }); 46 } 47 48 function getUTMFromSessionStorage() { 49 return { 50 utm_source: sessionStorage.getItem('utm_source') || '', 51 utm_medium: sessionStorage.getItem('utm_medium') || '', 52 utm_campaign: sessionStorage.getItem('utm_campaign') || '', 53 utm_content: sessionStorage.getItem('utm_content') || '', 54 utm_term: sessionStorage.getItem('utm_term') || '', 55 }; 56 } 57 58 59 // Ð¡Ð¾Ñ ÑанÑем UTM-меÑки в sessionStorage пÑи пеÑвом визиÑе 60 const urlParams = getUrlParams(); 61 saveUTMToSessionStorage(urlParams); 62 63 // ÐолÑÑаем UTM-меÑки из sessionStorage 64 const utmParams = getUTMFromSessionStorage(); 65 66 const forms = document.querySelectorAll('.cf-form'); 67 if (!forms.length) return; 68 69 forms.forEach((form, formIndex) => { 70 console.log(`ÐниÑиализаÑÐ¸Ñ ÑоÑÐ¼Ñ #${formIndex + 1}`); 71 72 const phoneInputs = form.querySelectorAll('.cf-phone'); 73 const nameInput = form.querySelector('[name="name"]'); 74 const emailInput = form.querySelector('[name="email"]'); 75 const msgInput = form.querySelector('[name="obr"]'); 76 77 const metrikaFields = form.querySelectorAll('.metrika_client_id'); 78 const roistatFields = form.querySelectorAll('.roistat'); 79 const utmSourceFields = form.querySelectorAll('.utm_source'); 80 const utmMediumFields = form.querySelectorAll('.utm_medium'); 81 const utmCampaignFields = form.querySelectorAll('.utm_campaign'); 82 const utmContentFields = form.querySelectorAll('.utm_content'); 83 const utmTermFields = form.querySelectorAll('.utm_term'); 84 85 const honeypotInput = form.querySelector('.nbf'); 86 const recaptchaInput = form.querySelector('.recaptcha-token'); 87 88 // ÐаÑки ÑелеÑона 89 let imInstances = []; 90 if (phoneInputs.length && typeof Inputmask !== 'undefined') { 91 phoneInputs.forEach(phoneInput => { 92 const im = new Inputmask("+7 (999) 999-99-99"); 93 im.mask(phoneInput); 94 imInstances.push(im); 95 }); 96 } 97 98 // ÐаполнÑем Ð¿Ð¾Ð»Ñ UTM из sessionStorage 99 if (utmParams.utm_source) { 100 utmSourceFields.forEach(f => f.value = utmParams.utm_source); 101 } 102 if (utmParams.utm_medium) { 103 utmMediumFields.forEach(f => f.value = utmParams.utm_medium); 104 } 105 if (utmParams.utm_campaign) { 106 utmCampaignFields.forEach(f => f.value = utmParams.utm_campaign); 107 } 108 if (utmParams.utm_content) { 109 utmContentFields.forEach(f => f.value = utmParams.utm_content); 110 } 111 if (utmParams.utm_term) { 112 utmTermFields.forEach(f =>
112 f.value = utmParams.utm_term); 113 } 114 115 // ÐбÑабоÑка оÑпÑавки ÑоÑÐ¼Ñ 116 form.addEventListener('submit', function (e) { 117 e.preventDefault(); 118 119 // ÐÑовеÑка honeypot 120 if (honeypotInput && honeypotInput.value.trim() !== '') { 121 showFormMessage(form, 'ÐÑибка: подозÑиÑелÑÐ½Ð°Ñ Ð°ÐºÑивноÑÑÑ!', false); 122 return; 123 } 124 125 // Ðаполнение полей roistat / metrika 126 roistatFields.forEach(f => { 127 if (!f.value) f.value = getCookie('roistat_visit') || ''; 128 }); 129 metrikaFields.forEach(f => { 130 if (!f.value) f.value = getCookie('_ym_uid') || ''; 131 }); 132 133 // ÐÑовеÑÑем обÑзаÑелÑнÑе Ð¿Ð¾Ð»Ñ 134 phoneInputs.forEach(inp => inp.classList.remove('error')); 135 if (nameInput) nameInput.classList.remove('error'); 136 if (emailInput) emailInput.classList.remove('error'); 137 138 let hasError = false; 139 phoneInputs.forEach((inp, i) => { 140 const val = inp.value.trim(); 141 if (!val) { 142 showFormMessage(form, 'Ðоле "ТелеÑон" обÑзаÑелÑное.', false); 143 inp.classList.add('error'); 144 hasError = true; 145 } else { 146 const im = imInstances[i]; 147 if (im && inp.inputmask && !inp.inputmask.isComplete()) { 148 showFormMessage(form, 'ÐожалÑйÑÑа, введиÑе полнÑй Ð½Ð¾Ð¼ÐµÑ ÑелеÑона.', false); 149 inp.classList.add('error'); 150 hasError = true; 151 } 152 } 153 }); 154 if (hasError) return; 155 156 const formData = new FormData(form); 157 158 // ÐобавлÑем UTM-меÑки в formData 159 Object.entries(utmParams).forEach(([key, value]) => { 160 if (value) { 161 formData.set(key, value); 162 } 163 }); 164 165 // ÐлокиÑÑем Ð¿Ð¾Ð»Ñ 166 form.classList.add('cf-form--loading'); 167 const allFields = form.querySelectorAll('input, button, select, textarea:not([name="sessid"])'); 168 allFields.forEach(fld => fld.disabled = true); 169 170 grecaptcha.ready(() => { 171 grecaptcha.execute(siteKey, { action: 'submit' }).then(token => { 172 formData.set('g_recaptcha_token', token); 173 174 fetch('/local/ajax/orderform_handler.php', { 175 method: 'POST', 176 body: formData 177 }) 178 .then(resp => resp.json()) 179 .then(data => { 180 if (data.status === 'success') { 181 // Ð¦ÐµÐ»Ñ Ð¯.ÐеÑÑики 182 const goalName = form.dataset.ymGoal; 183 if (goalName && typeof ym !== 'undefined') { 184 ym(83439094, 'reachGoal', goalName); 185 } 186 showFormMessage(form, data.message, true); 187 form.reset(); 188 189 // СбÑÐ¾Ñ Ð¼Ð°Ñок 190 phoneInputs.forEach(inp => { 191 if (inp.inputmask) inp.inputmask.remove(); 192 }); 193 imInstances = []; 194 phoneInputs.forEach(inp => { 195 const newIM = new Inputmask("+7 (999) 999-99-99"); 196 newIM.mask(inp); 197 imInstances.push(newIM); 198 }); 199 } else { 200 showFormMessage(form, data.message, false); 201 } 202 }) 203 .catch(err => { 204 console.error('Fetch error:', err); 205 showFormMessage(form, 'ÐÑоизоÑла оÑибка пÑи оÑпÑавке. ÐопÑобÑйÑе позже.', false); 206 }) 207 .finally(() => { 208 form.classList.remove('cf-form--loading'); 209 allFields.forEach(fld => fld.disabled = false); 210 }); 211 }); 212 }); 213 }); 214 }); 215});
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.