1(function($) { 2 $(function() { 3 // GEO selection menu 4 function onGeoLocationSelectorClick(e) { 5 e.stopPropagation(); 6 7 var el = e.currentTarget; 8 9 var div = $("#list-geo-content"); 10 11 if ($("#list-geo-content:visible").length && div[0]._el == el) { 12 $("#list-geo-content").hide(); 13 return false; 14 } 15 16 if ($("#list-geo-content").length == 0) { 17 $("#header-map").after('<div id="list-geo-content"></div>'); 18 $("#list-geo-content") 19 .css({ 20 position: "absolute", 21 padding: 5, 22 backgroundColor: "white", 23 borderColor: "#1466B2", 24 borderWidth: 1, 25 borderStyle: "solid", 26 zIndex: "9999", 27 }) 28 .hide(); 29 } 30 31 var _parent = $(el).parent(); 32 var _arr = $(_parent).children(".arrow"); 33 var _pos = _parent.offset(); 34 35 $("#list-geo-content").css({ 36 left: _pos.left, 37 top: _pos.top + 2 + _parent.outerHeight() - _arr.outerHeight(), 38 width: _parent.width() - 12, 39 }); 40 41 div = $("#list-geo-content"); 42 div[0]._el = el; 43 44 $(el).click(function() { 45 $("#list-geo-content").hide(); 46 }); 47 48 $.get(el.href, function(data) { 49 $("#list-geo-content").html(data).show(); 50 $("#list-geo-content").prepend( 51 '<small onclick="$(\'#list-geo-content\').hide()" style="float:right;cursor:pointer">закÑÑÑÑ</small>' 52 ); 53 }); 54 return false; 55 } 56 57 $("a.list-geo-locations-selector").on("click", onGeoLocationSelectorClick); 58 59 const $body = $("body"); 60 61 // scroll to top 62 $scrollToTop = $("<button>", { text: "ÐавеÑÑ ", class: "go-top" }); 63 $scrollToTop.appendTo($body); 64 $doc = $(document); 65 66 const SCROLL_WH = window.innerHeight * 2; 67 68 let scrollTimer; 69 70 function onScrollEnd() { 71 window.clearTimeout(scrollTimer); 72 $scrollToTop.addClass("static"); 73 } 74 75 function onScroll(e) { 76 $scrollToTop.toggleClass("show", $doc.scrollTop() > SCROLL_WH); 77 $scrollToTop.removeClass("static"); 78 window.clearTimeout(scrollTimer); 79 window.setTimeout(onScrollEnd, 1000); 80 } 81 82 $doc.on("scroll", onScroll); 83 onScroll(); 84 85 $scrollToTop.click(function(e) { 86 e.stopPropagation(); 87 $("html, body").animate({ scrollTop: 0 }, "slow"); 88 return false; 89 }); 90 91 // accordion 92 $(".accordion__handler").on("click", function(e) { 93 let $this = $(this); 94 if ($(e.target).is("a")) { 95 return; 96 } 97 $currentItem = $this.parent(".accordion__item"); 98 if ($currentItem.is(".open")) { 99 $currentItem.removeClass("open"); 100 } else { 101 $(this) 102 .parent(".accordion__item") 103 .parent() 104 .children(".accordion__item") 105 .removeClass("open"); 106 $currentItem.addClass("open"); 107 } 108 }); 109 110 //scroll-page-indicator (static width only for now) 111 112 $(".scroll-page-indicator").filter(function() { 113 const $this = $(this); 114 const $scrollWindow = $this.parent(); 115 const scrollWidth = $scrollWindow[0].scrollWidth; 116 const pointsCount = Math.round(scrollWidth / $scrollWindow.width()); 117 const scrollWindowWidth = $scrollWindow.width(); 118 let $points; 119 120 function switchTo(i) { 121 $points.removeClass("active").eq(i).addClass("active"); 122 } 123 124 for (let i = 0; i < pointsCount; i++) { 125 let $p = $("<span>", { class: "scroll-page-point" }); 126 if (i === 0) $p.addClass("active"); 127 $p.on("click", function() { 128 $scrollWindow.animate({ scrollLeft: scrollWindowWidth * i }, "slow"); 129 }); 130 $this.append($p); 131 } 132 133 $points = $this.children(); 134 135 $scrollWindow[0].addEventListener( 136 "scroll", 137 function() { 138 switchTo( 139 Math.round( 140 (pointsCount * $scrollWindow[0].scrollLeft) / scrollWidth 141 ) 142 ); 143 }, 144 { 145 passive: true, 146 } 147 ); 148 }); 149 }); 150 // datalist 151 (function() { 152 const d = window.document; 153 const ajaxDataLists = d.querySelectorAll('datalist[data-src]'); 154 Array.prototype.forEach.call(ajaxDataLists, function(dataList) { 155 const src = dataList.dataset.src; 156 const input = d.querySelector('input[list="' + dataList.id + '"]') 157 input.addEventListener('change', function() { 158 const selectedOption = dataList.querySelector("option[value='" + this.value + "']"); 159 const hiddenInput = input.parentElement.querySelector('[type="hidden"]'); 160 if (hiddenInput) { 161 hiddenInput.value = selectedOption ? selectedOption.dataset.value : 0; 162 } 163 }); 164 input.addEventListener('keypress', function() { 165 fetch(src.replace('{q}', input.value)).then(function(d) { 166 return d.json(); 167 }).then(function(items) { 168 dataList.innerHTML = ''; 169 for (let cityId in items) { 170 let item = items[cityId]; 171 const option = d.createElement('option'); 172 option.value = item; 173 option.dataset.value = cityId; 174 dataList.appendChild(option); 175 } 176 }); 177 }) 178 }); 179 })(); 180 (function ajaxForm() { 181 Array.prototype.forEach.call(document.querySelectorAll('.ajax-form'), function(form) { 182 form.addEventListener('submit', function(e) { 183 e.preventDefault(); 184 const url = form.getAttribute('action') || window.location.href; 185 const submitButton = form.querySelector('[type="submit"]'); 186 submitButton.disabled = true; 187 fetch(url, { 188 method: 'POST', 189 headers: { 190 'Accept': 'application/json', 191 }, 192 body: new FormData(form) 193 }).then(function(d) { 194 return d.json(); 195 }).then(function(r) {
196 const overlay = document.createElement('div'); 197 const msg = document.createElement('p'); 198 const ok = document.createElement('button'); 199 200 submitButton.disabled = false; 201 202 ok.innerText = 'OK'; 203 msg.innerText = r.message; 204 ok.classList.add('primary'); 205 overlay.classList.add('ajax-form-overlay'); 206 overlay.appendChild(msg); 207 overlay.appendChild(ok); 208 209 ok.addEventListener('click', function() { 210 form.removeChild(overlay); 211 }); 212 213 setTimeout(function() { 214 form.removeChild(overlay); 215 }, 60000); 216 217 218 form.appendChild(overlay); 219 form.reset(); 220 }); 221 }); 222 }); 223 })(); 224 (function countDown() { 225 function unwrap(el) { 226 const parent = el.parentNode; 227 while (el.firstChild) parent.insertBefore(el.firstChild, el); 228 parent.removeChild(el); 229 } 230 const d = window.document; 231 const elements = d.querySelectorAll('[data-countdown]'); 232 Array.prototype.forEach.call(elements, function(element) { 233 const countDownDate = (+new Date()) + (+element.dataset.countdown); 234 let x = setInterval(function() { 235 let now = +new Date(); 236 let distance = countDownDate - now; 237 let minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); 238 let seconds = Math.floor((distance % (1000 * 60)) / 1000); 239 240 element.innerHTML = minutes + ":" + (seconds >= 10 ? seconds : '0' + seconds); 241 242 if (distance < 1000) { 243 clearInterval(x); 244 let mpFs = d.querySelector(".disabled-fieldset"); 245 unwrap(mpFs); 246 element.parentNode.remove(element); 247 } 248 }, 1000); 249 }); 250 })(); 251 (function formValidation() { 252 const VALIDATION_PATTERNS = { 253 tel: /^\+?[\d() -]*$/, 254 email: /^[@A-Za-zÐ-Яа-ÑÐÑ 0-9_.-]*$/, 255 number: /^\d*$/, 256 }; 257 258 const EVENTS = [ 259 "input", 260 "keydown", 261 "keyup", 262 "mousedown", 263 "mouseup", 264 "select", 265 "contextmenu", 266 "drop", 267 ]; 268 269 function setInputFilter(input, inputFilter) { 270 if (!inputFilter) return; 271 272 let filter = 273 typeof inputFilter === "function" 274 ? inputFilter 275 : function(value) { 276 return inputFilter.test(value); 277 }; 278 279 EVENTS.forEach(function(event) { 280 input.addEventListener(event, function() { 281 if (filter(this.value)) { 282 this.oldValue = this.value; 283 this.oldSelectionStart = this.selectionStart; 284 this.oldSelectionEnd = this.selectionEnd; 285 } else if (this.hasOwnProperty("oldValue")) { 286 this.value = this.oldValue; 287 this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd); 288 } 289 }); 290 }); 291 } 292 293 function validateInput(_) { 294 const isValid = this.checkValidity(); 295 const validity = this.validity; 296 let errorText = "Ðоле не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑÑм"; 297 298 if (isValid) { 299 this.classList.remove("error"); 300 } else { 301 this.classList.add("error"); 302 } 303 304 if (validity.typeMismatch) { 305 errorText = "ÐевеÑнÑй ÑоÑмаÑ"; 306 } 307 308 const errSpan = this.parentElement.querySelector("span.error"); 309 if (errSpan) { 310 errSpan.innerHTML = isValid ? " " : errorText; 311 } 312 } 313 314 function resetInputError(_) { 315 this.classList.remove("error"); 316 const errSpan = this.parentElement.querySelector("span.error"); 317 if (errSpan) { 318 errSpan.innerHTML = " "; 319 } 320 } 321 322 function initForm(formElement) { 323 const inputsWithPattern = formElement.querySelectorAll('input:not([type="submit"])'); 324 325 Array.prototype.forEach.call(inputsWithPattern, function(input) { 326 let type = input.type; 327 if (type == 'text') type = input.id; 328 if (type == 'mail') type = 'email'; 329 setInputFilter(input, VALIDATION_PATTERNS[type || "text"]); 330 331 input.addEventListener("blur", validateInput); 332 input.addEventListener("input", resetInputError); 333 }); 334 } 335 336 Array.prototype.forEach.call(document.querySelectorAll("form"), initForm); 337 })(); 338})($);
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.