1document.addEventListener('DOMContentLoaded', function () { 2 const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); 3 tooltipTriggerList.forEach(function (el) { 4 new bootstrap.Tooltip(el); 5 }); 6 7 $(function(){ 8 $('input[type="tel"]').mask('+7 (999) 999-99-99'); 9 }); 10 11 12 13 const clampBlocks = document.querySelectorAll('[data-lineclump]'); 14 15 function isClamped(el) { 16 return el.scrollHeight > el.clientHeight + 1; 17 } 18 19 function bindBlock(el) { 20 21 const btn = 22 el.parentElement?.querySelector('[data-lineclump-btn]') || 23 (el.nextElementSibling?.matches('[data-lineclump-btn]') ? el.nextElementSibling : null); 24 25 if (!btn) return; 26 27 const openText = btn.dataset.open || 'Read more'; 28 const hideText = btn.dataset.hide || 'Hide'; 29 30 const updateButtonVisibility = () => { 31 if (el.classList.contains('is-open')) { 32 btn.hidden = false; 33 return; 34 } 35 36 btn.hidden = !isClamped(el); 37 }; 38 39 requestAnimationFrame(updateButtonVisibility); 40 41 window.addEventListener('resize', updateButtonVisibility); 42 43 btn.addEventListener('click', () => { 44 45 const opened = el.classList.toggle('is-open'); 46 47 btn.classList.toggle('is-open', opened); 48 49 btn.textContent = opened ? hideText : openText; 50 51 requestAnimationFrame(updateButtonVisibility); 52 53 }); 54 } 55 56 clampBlocks.forEach(bindBlock); 57}); 58$(document).on('click', 'button[data-product][data-bs-target]', function () { 59 var productName = $(this).data('product'); 60 var modalSelector = $(this).data('bs-target'); 61 62 if (!productName || !modalSelector) return; 63 64 var $modal = $(modalSelector); 65 66 if (!$modal.length) return; 67 68 $modal.find('input[name="PRODUCT"]').val(productName); 69}); 70$('body').on('click', '.compare-add', function() { 71 var compareID = $(this).attr('data-id'); 72 if($(this).hasClass('active')) { 73 var doAction = 'DELETE_FROM_COMPARE_LIST'; 74 } else { 75 var doAction = 'ADD_TO_COMPARE_LIST'; 76 } 77 addCompare(compareID, doAction); 78}); 79$('body').on('click', '.favorite-add', function() { 80 var favorID = $(this).attr('data-id'); 81 if($(this).hasClass('active')) 82 var doAction = 'delete'; 83 else 84 var doAction = 'add'; 85 86 addFavorite(favorID, doAction); 87}); 88function addCompare(id, action){ 89 var AddedGoodId = id; 90 var GoodAction = action; 91 $.get("/ajax/list_compare.php", 92 {action: GoodAction, id: AddedGoodId}, 93 function(data) { 94 if($('.compare-add[data-id="'+id+'"]').hasClass('active')) { 95 $('.compare-add[data-id="'+id+'"]').removeClass('active'); 96 } else { 97 $('.compare-add[data-id="'+id+'"]').addClass('active'); 98 } 99 } 100 ); 101} 102function addFavorite(id, action){ 103 var param = 'id='+id+"&action="+action; 104 $.ajax({ 105 url: '/ajax/favorites.php', // URL оÑпÑавки запÑоÑа 106 type: "GET", 107 dataType: "html", 108 data: param, 109 success: function(response) { // ÐÑли ÐаннÑе оÑпÑÐ°Ð²Ð»ÐµÐ½Ñ ÑÑпеÑно 110 var result = $.parseJSON(response); 111 if(result == 1) { // ÐÑли вÑÑ ÑÑÑко, Ñо вÑполнÑем дейÑÑвиÑ, коÑоÑÑе показÑваÑÑ, ÑÑо даннÑе оÑпÑÐ°Ð²Ð»ÐµÐ½Ñ :) 112 $('.favorite-add[data-id="'+id+'"]').addClass('active'); 113 var wishCount = parseInt($('#want .col').html()) + 1; 114 $('#want .col').html(wishCount); // ÐизÑалÑно менÑем колиÑеÑÑво Ñ Ð¸ÐºÐ¾Ð½ÐºÐ¸ 115 } 116 if(result == 2){ 117 $('.favorite-add[data-id="'+id+'"]').removeClass('active'); 118 var wishCount = parseInt($('#want .col').html()) - 1; 119 $('#want .col').html(wishCount); // ÐизÑалÑно менÑем колиÑеÑÑво Ñ Ð¸ÐºÐ¾Ð½ÐºÐ¸ 120 } 121 }, 122 error: function(jqXHR, textStatus, errorThrown){ // ÐÑли оÑибка, Ñо вÑкладÑваем пеÑÐ°Ð»Ñ Ð² конÑÐ¾Ð»Ñ 123 console.log('Error: '+ errorThrown); 124 } 125 }); 126} 127function updateHeaderBasketCount() { 128 return $.getJSON('/ajax/basket/count.php') 129 .done(function (res) { 130 if (!res?.success) return; 131 132 const $root = $('#header-basket-line'); 133 134 // 1) ÑÑандаÑÑнÑй биÑÑикÑовÑй ÑелекÑÐ¾Ñ (ÑаÑÑо вÑÑÑеÑаеÑÑÑ) 135 let $countNode = $root.find('[data-entity="basket-items-count"]').first(); 136 137 // 2) запаÑнÑе ваÑианÑÑ (под ÑазнÑе ÑаблонÑ) 138 if (!$countNode.length) $countNode = $root.find('.basket-items-count, .js-basket-count, .basket-count').first(); 139 140 if ($countNode.length) { 141 $countNode.text(res.count); 142 } else { 143 // еÑли вообÑе не наÑли Ñзел â вÑведем в конÑолÑ, ÑÑÐ¾Ð±Ñ ÑÑ Ð´Ð°Ð»Ð° мне ÑеалÑнÑй ÑелекÑÐ¾Ñ 144 console.warn('Ðе наÑÑл Ñзел ÑÑÑÑÑика внÑÑÑи #header-basket-line. ÐÐ¾Ð±Ð°Ð²Ñ data-entity="basket-items-count" на нÑжнÑй <span>.'); 145 } 146 }); 147} 148$(document).on('click', '.buy-btn', function (e) { 149 e.preventDefault(); 150 151 const modalCart = document.getElementById('modal'); 152 const cart_modal = new bootstrap.Modal(modalCart); 153 154 const $btn = $(this); 155 const productId = parseInt($btn.attr('data-id'), 10); 156 if (!productId) return; 157 158 // ÐеÑÑм знаÑение ближайÑего input[name="b_qnt"] 159 const $qnt = $btn.closest('.product-item-actions-block') 160 .find('input[name="b_qnt"]') 161 .first(); 162 163 let qty = $qnt.length ? $qnt.val() : 1;
164 qty = (String(qty).replace(',', '.')); 165 qty = parseFloat(qty); 166 if (!qty || qty <= 0) qty = 1; 167 168 $btn.prop('disabled', true).addClass('is-loading'); 169 170 $.ajax({ 171 url: '/ajax/basket/add.php', 172 method: 'POST', 173 dataType: 'json', 174 data: { 175 sessid: BX.bitrix_sessid(), 176 product_id: productId, 177 quantity: qty 178 } 179 }) 180 .done(function (res) { 181 if (!res || !res.success) { 182 console.error(res); 183 return; 184 } 185 $('#modal .modal-header .cnt').text(res.header); 186 $('#modal .modal-body').html(res.content); 187 cart_modal.show(); 188 updateHeaderBasketCount(); 189 }) 190 .fail(function (xhr) { 191 console.error(xhr); 192 }) 193 .always(function () { 194 $btn.prop('disabled', false).removeClass('is-loading'); 195 }); 196}); 197$(function () { 198 updateHeaderBasketCount(); 199}); 200$(document).ready(function() { 201 const THANKS_URL = '/spassibo/'; 202 203 function redirectToThanks() { 204 sessionStorage.setItem('thanksBackUrl', window.location.href); 205 window.location.href = THANKS_URL; 206 } 207 208 function lockForm($form) { 209 $form.data('isSubmitting', true); 210 $form.find('button[type="submit"], input[type="submit"]').prop('disabled', true).addClass('is-loading'); 211 } 212 213 function unlockForm($form) { 214 $form.data('isSubmitting', false); 215 $form.find('button[type="submit"], input[type="submit"]').prop('disabled', false).removeClass('is-loading'); 216 } 217 218 function showSubmitPreloader() { 219 const preloader = document.getElementById('submit-preloader'); 220 if (preloader) { 221 preloader.hidden = false; 222 document.body.classList.add('is-submitting-form'); 223 } 224 } 225 226 function hideSubmitPreloader() { 227 const preloader = document.getElementById('submit-preloader'); 228 if (preloader) { 229 preloader.hidden = true; 230 document.body.classList.remove('is-submitting-form'); 231 } 232 } 233 234 function hideModal(modalId) { 235 if (!modalId) return; 236 237 const modalEl = document.getElementById(modalId); 238 if (!modalEl) return; 239 240 bootstrap.Modal.getOrCreateInstance(modalEl).hide(); 241 } 242 243 function resetForm($form) { 244 $form.find('input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]), textarea').val(''); 245 $form.find('input[type="checkbox"], input[type="radio"]').prop('checked', false); 246 $form.trigger('reset'); 247 } 248 249 function hideError($form) { 250 $form.find('.alert.alert-danger').addClass('hidden'); 251 } 252 253 function showError($form, $str = "") { 254 var $alert = $form.find('.alert.alert-danger'); 255 if ($alert.length === 0) { 256 $alert = $('<div class="mb-3 alert alert-danger hidden"></div>'); 257 $form.find('#captcha-container').after($alert); 258 } 259 clearTimeout($alert.data('timer')); 260 $alert.removeClass('hidden').text($str); 261 var timer = setTimeout(function() { 262 $alert.addClass('hidden').text(""); 263 }, 3000); 264 $alert.data('timer', timer); 265 } 266 267 function submitAjaxForm(options) { 268 const $form = $(options.formSelector); 269 270 if (!$form.length) return; 271 272 $form.off('submit.ajaxForm').on('submit.ajaxForm', function(e) { 273 e.preventDefault(); 274 275 const curForm = $(this); 276 277 if (curForm.data('isSubmitting')) { 278 console.warn('[FORM BLOCKED] already submitting'); 279 return; 280 } 281 282 hideError(curForm); 283 lockForm(curForm); 284 showSubmitPreloader(); 285 286 const runRequest = function() { 287 $.ajax({ 288 type: options.method || 'POST', 289 url: options.url, 290 data: options.getData ? options.getData(curForm) : curForm.serialize(), 291 dataType: options.dataType || 'json', 292 success: function(result) { 293 const isSuccess = options.isSuccess 294 ? options.isSuccess(result) 295 : (result.status === 'success'); 296 297 if (isSuccess) { 298 if (typeof options.goal === 'function') { 299 options.goal(result, curForm); 300 } else if (options.goal && typeof window.ym === 'function') { 301 ym(677558, 'reachGoal', options.goal); 302 } 303 304 resetForm(curForm); 305 hideError(curForm); 306 hideModal(options.hideModalId); 307 308 sessionStorage.setItem('thanksBackUrl', window.location.href);
309 window.location.href = '/spassibo/'; 310 } else { 311 hideSubmitPreloader(); 312 unlockForm(curForm); 313 showError(curForm, result.errors); 314 } 315 }, 316 317 error: function(xhr, status, error) { 318 console.error('[AJAX ERROR]', { 319 status: status, 320 error: error, 321 httpStatus: xhr.status, 322 responseText: xhr.responseText 323 }); 324 325 hideSubmitPreloader(); 326 unlockForm(curForm); 327 showError(curForm); 328 } 329 }); 330 }; 331 runRequest(); 332 }); 333 } 334 335 submitAjaxForm({ 336 formSelector: '#call_form', 337 url: '/ajax/call.modal.handler.php', 338 hideModalId: 'call-modal', 339 goal: 'zakazzvonka' 340 }); 341 342 submitAjaxForm({ 343 formSelector: '#callback-inline', 344 url: '/ajax/call.modal.handler.php', 345 goal: 'zakazzvonka' 346 }); 347 348 submitAjaxForm({ 349 formSelector: '#get-discount-form', 350 url: '/ajax/discount.form.handler.php', 351 debug: true 352 }); 353 354 submitAjaxForm({ 355 formSelector: '#service-modal-form', 356 url: '/ajax/form_ukladka_handler.php', 357 hideModalId: 'service-modal', 358 debug: true 359 }); 360 361 submitAjaxForm({ 362 formSelector: '#ask-form', 363 url: '/ajax/ask.modal.handler.php', 364 hideModalId: 'ask-modal', 365 goal: 'zadatvopros' 366 }); 367 368 submitAjaxForm({ 369 formSelector: '#ask-question-new', 370 url: '/ajax/kp.handler.php', 371 goal: 'zadatvopros' 372 }); 373 374 submitAjaxForm({ 375 formSelector: '#cheaper-form', 376 url: '/ajax/cheaper.php', 377 hideModalId: 'cheaper-modal' 378 }); 379 /* 380 submitAjaxForm({ 381 formSelector: '#vip-form', 382 url: '/ajax/vip-form.php', 383 hideModalId: 'vip-modal', 384 debug: true, 385 isSuccess: function(result) { 386 return result.status === 'success' || result.text !== 'Captcha'; 387 } 388 }); 389 390 submitAjaxForm({ 391 formSelector: '#example-form', 392 url: '/ajax/example-form.php', 393 hideModalId: 'example-modal', 394 isSuccess: function(result) { 395 return result.status === 'success' || result.text !== 'Captcha'; 396 } 397 });*/ 398 399 submitAjaxForm({ 400 formSelector: '#ask-price', 401 url: '/ajax/ask.pricelist.handler.php', 402 debug: true 403 }); 404 405 submitAjaxForm({ 406 formSelector: '#contact-form', 407 url: '/ajax/contact-form.handler.php', 408 hideModalId: 'contact-us-modal' 409 }); 410 411 submitAjaxForm({ 412 formSelector: '#subscribe', 413 url: '/ajax/subscribe.handler.php', 414 isSuccess: function(result) { 415 return result.status === 'success'; 416 }, 417 debug: true 418 }); 419 420 submitAjaxForm({ 421 formSelector: '#oneclick-form', 422 url: '/ajax/one-click-new.php', 423 hideModalId: 'one-click-modal', 424 debug: true, 425 isSuccess: function(result) { 426 return result.status === 'ok'; 427 }, 428 errorAsSuccess: function(xhr) { 429 try { 430 const result = xhr.responseJSON; 431 return result && result.status === 'ok'; 432 } catch (e) { 433 return false; 434 } 435 } 436 }); 437 438 submitAjaxForm({ 439 formSelector: '#review-form', 440 url: '/ajax/reviews.handler.php', 441 hideModalId: 'review-modal', 442 method: 'POST', 443 dataType: 'json', 444 contentType: false, 445 processData: false, 446 getData: function() { 447 const form = document.getElementById('review-form'); 448 const formData = new FormData(form); 449 450 const fileInput = $('#review-form input[name="userfile"]')[0]; 451 if (fileInput && fileInput.files && fileInput.files[0]) { 452 formData.set('file_attach', fileInput.files[0]); 453 } 454 455 formData.set('comment', $('#review-form textarea').val()); 456 457 return formData; 458 }, 459 isSuccess: function() { 460 return true; 461 } 462 }); 463 464 $('#vip-form').on('submit', function(e) { 465 e.preventDefault(); 466 467 const curForm = $(this); 468 469 if (curForm.data('isSubmitting')) { 470 return; 471 } 472 473 hideError(curForm); 474 lockForm(curForm); 475 showSubmitPreloader(); 476 477 $.ajax({ 478 type: 'POST', 479 url: '/ajax/vip-form.php', 480 data: curForm.serialize(), 481 dataType: 'json', 482 headers: { 483 'X-Requested-With': 'XMLHttpRequest' 484 }, 485 success: function(result) { 486 console.log('vip-form result:', result); 487 488 if (result.status === 'success') { 489 resetForm(curForm); 490 hideError(curForm); 491 hideModal('vip-modal'); 492 sessionStorage.setItem('thanksBackUrl', window.location.href);
493 window.location.href = '/spassibo/'; 494 } else { 495 hideSubmitPreloader(); 496 unlockForm(curForm); 497 showError(curForm, result.errors); 498 } 499 }, 500 error: function(xhr) { 501 console.log('vip-form xhr error:', xhr); 502 hideSubmitPreloader(); 503 unlockForm(curForm); 504 showError(curForm); 505 } 506 }); 507 }); 508 509 $('#example-form').on('submit', function(e) { 510 e.preventDefault(); 511 512 const curForm = $(this); 513 514 if (curForm.data('isSubmitting')) { 515 return; 516 } 517 518 hideError(curForm); 519 lockForm(curForm); 520 showSubmitPreloader(); 521 522 $.ajax({ 523 type: 'POST', 524 url: '/ajax/example-form.php', 525 data: curForm.serialize(), 526 dataType: 'json', 527 headers: { 528 'X-Requested-With': 'XMLHttpRequest' 529 }, 530 success: function(result) { 531 console.log('example-form result:', result); 532 533 if (result.status === 'success') { 534 resetForm(curForm); 535 hideError(curForm); 536 hideModal('example-modal'); 537 sessionStorage.setItem('thanksBackUrl', window.location.href); 538 window.location.href = '/spassibo/'; 539 } else { 540 hideSubmitPreloader(); 541 unlockForm(curForm); 542 showError(curForm, result.errors); 543 } 544 }, 545 error: function(xhr) { 546 console.log('example-form xhr error:', xhr); 547 hideSubmitPreloader(); 548 unlockForm(curForm); 549 showError(curForm); 550 } 551 }); 552 }); 553});
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.