1/* 2You can use this file with your scripts. 3It will not be overwritten when you upgrade solution. 4*/ 5 6document.addEventListener("DOMContentLoaded", function() { 7 var btn = document.getElementById("cookie-accept"); 8 if (btn) { 9 btn.addEventListener("click", function(e) { 10 e.preventDefault(); 11 fetch('/local/ajax/cookie_accept.php', { 12 method: "POST", 13 headers: { 14 "Content-Type": "application/x-www-form-urlencoded" 15 }, 16 body: "cookie_accept=1", 17 credentials: 'same-origin' 18 }).then(response => response.json()).then(data => { 19 if (data.status === "ok") { 20 document.getElementById("cookie-consent").style.display = "none"; 21 } 22 } 23 ); 24 }); 25 } 26}); 27 28$(function(){ 29 // ФÑнкÑÐ¸Ñ Ð¸Ð½Ð¸ÑиализаÑии авÑоподÑÑановки Ð´Ð»Ñ Ð¿Ð¾Ð»Ñ Ð³Ð¾Ñода в бÑÑÑÑом заказе 30 function initOcbCityAutocomplete() { 31 var $cityInput = $('#one_click_buy_id_CITY'); 32 33 if (!$cityInput.length) return; 34 if ($cityInput.data('autocomplete-inited')) return; 35 36 // ÐобавлÑем конÑÐµÐ¹Ð½ÐµÑ Ð´Ð»Ñ Ð¿Ð¾Ð´Ñказок 37 var $wrap = $cityInput.closest('.input'); 38 if (!$wrap.length) { 39 $cityInput.wrap('<div class="input" style="position:relative;"></div>'); 40 $wrap = $cityInput.parent(); 41 } 42 43 // Создаем конÑÐµÐ¹Ð½ÐµÑ Ð´Ð»Ñ ÑезÑлÑÑаÑов 44 var $suggestions = $cityInput.siblings('.city-suggestions'); 45 if (!$suggestions.length) { 46 $suggestions = $('<div class="city-suggestions" style="display:none; position:absolute; z-index:9999; background:#fff; border:1px solid #ddd; border-radius:4px; max-height:200px; overflow-y:auto; width:100%; margin-top:2px;"></div>'); 47 $wrap.css('position', 'relative'); 48 $wrap.append($suggestions); 49 } 50 51 var currentRequest = null; 52 var lastQuery = ''; 53 54 // ФÑнкÑÐ¸Ñ Ð¿Ð¾Ð¸Ñка - без задеÑжки, ÑÑÐ°Ð·Ñ 55 function performSearch(query) { 56 lastQuery = query; 57 58 // ÐÑменÑем пÑедÑдÑÑий запÑÐ¾Ñ 59 if (currentRequest) { 60 currentRequest.abort(); 61 currentRequest = null; 62 } 63 64 if (!query || query.length < 2) { 65 $suggestions.hide().empty(); 66 return; 67 } 68 69 // ÐоказÑваем индикаÑÐ¾Ñ 70 $suggestions.html('<div style="padding:8px 12px; color:#999;">ÐоиÑк...</div>').show(); 71 72 currentRequest = $.ajax({ 73 url: '/local/ajax/shipping_cities.php', 74 method: 'GET', 75 dataType: 'json', 76 data: { q: query }, 77 success: function(response) { 78 currentRequest = null; 79 80 // ÐÑовеÑÑем акÑÑалÑноÑÑÑ 81 if (lastQuery !== query) { 82 return; 83 } 84 85 var cities = response && response.cities ? response.cities : []; 86 87 if (!cities.length) { 88 $suggestions.html('<div style="padding:8px 12px; color:#999;">ÐиÑего не найдено</div>').show(); 89 return; 90 } 91 92 var html = ''; 93 $.each(cities, function(index, city) { 94 var cityName = city.name || city; 95 html += '<div class="city-suggestion-item" data-city-name="' + cityName + '" style="padding:8px 12px; cursor:pointer; border-bottom:1px solid #f0f0f0;">'; 96 html += cityName; 97 html += '</div>'; 98 }); 99 100 $suggestions.html(html).show(); 101 102 // ÐбÑабоÑÑики кликов 103 $suggestions.find('.city-suggestion-item').on('click', function() { 104 var cityName = $(this).data('city-name'); 105 $cityInput.val(cityName); 106 $suggestions.hide().empty(); 107 $cityInput.trigger('change'); 108 lastQuery = cityName; 109 }).on('mouseenter', function() { 110 $(this).css('background', '#f5f5f5'); 111 }).on('mouseleave', function() { 112 $(this).css('background', ''); 113 }); 114 }, 115 error: function() { 116 currentRequest = null; 117 if (lastQuery === query) { 118 $suggestions.hide().empty(); 119 } 120 } 121 }); 122 } 123 124 // ÐбÑабоÑÑик ввода - Ñ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»Ñной задеÑжкой 125 var searchTimer = null; 126 $cityInput.on('input.ocbCity', function() { 127 var query = $.trim($(this).val()); 128 129 // СбÑаÑÑваем ÑÐ°Ð¹Ð¼ÐµÑ 130 clearTimeout(searchTimer); 131 132 // ÐÑли запÑÐ¾Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ð»ÑÑ 133 if (query !== lastQuery) { 134 if (query.length < 2) { 135 $suggestions.hide().empty(); 136 lastQuery = query; 137 return; 138 } 139 140 // ÐаленÑÐºÐ°Ñ Ð·Ð°Ð´ÐµÑжка Ð´Ð»Ñ Ð¿Ð»Ð°Ð²Ð½Ð¾ÑÑи 141 searchTimer = setTimeout(function() { 142 performSearch(query); 143 }, 150); 144 } 145 }); 146 147 // ÐÑи поÑеÑе ÑокÑÑа - ÑкÑÑваем
148 $cityInput.on('blur.ocbCity', function() { 149 setTimeout(function() { 150 $suggestions.hide().empty(); 151 }, 300); 152 }); 153 154 // ÐлавиÑи 155 $cityInput.on('keydown.ocbCity', function(e) { 156 var $items = $suggestions.find('.city-suggestion-item'); 157 if (!$items.length || !$suggestions.is(':visible')) return; 158 159 var $active = $items.filter('[style*="background: rgb(245, 245, 245)"]'); 160 161 if (e.key === 'ArrowDown') { 162 e.preventDefault(); 163 if ($active.length) { 164 var next = $active.next(); 165 if (next.length) { 166 $active.css('background', ''); 167 next.css('background', '#f5f5f5'); 168 } 169 } else { 170 $items.first().css('background', '#f5f5f5'); 171 } 172 } else if (e.key === 'ArrowUp') { 173 e.preventDefault(); 174 if ($active.length) { 175 var prev = $active.prev(); 176 if (prev.length) { 177 $active.css('background', ''); 178 prev.css('background', '#f5f5f5'); 179 } 180 } else { 181 $items.last().css('background', '#f5f5f5'); 182 } 183 } else if (e.key === 'Enter') { 184 if ($active.length) { 185 e.preventDefault(); 186 $active.trigger('click'); 187 } 188 } else if (e.key === 'Escape') { 189 $suggestions.hide().empty(); 190 } 191 }); 192 193 // ÐакÑÑваем пÑи клике вне 194 $(document).on('click.ocbCity', function(e) { 195 if (!$(e.target).closest('.input').length) { 196 $suggestions.hide().empty(); 197 } 198 }); 199 200 $cityInput.data('autocomplete-inited', true); 201 } 202 203// ÐниÑиализиÑÑем пÑи загÑÑзке модалки бÑÑÑÑого заказа 204 $(document).on('click', '*[data-event="jqm"][data-name="ocb"]', function() { 205 // ÐниÑиализиÑÑем ÑеÑез некоÑоÑое вÑÐµÐ¼Ñ Ð¿Ð¾Ñле оÑкÑÑÑÐ¸Ñ 206 setTimeout(initOcbCityAutocomplete, 500); 207 }); 208 209// Также иниÑиализиÑÑем ÑеÑез onLoadjqm 210 var originalOnLoadjqm = window.onLoadjqm || function() {}; 211 window.onLoadjqm = function(name, hash, _this) { 212 // ÐÑзÑваем оÑигиналÑнÑÑ ÑÑнкÑÐ¸Ñ 213 if (typeof originalOnLoadjqm === 'function') { 214 originalOnLoadjqm(name, hash, _this); 215 } 216 217 // ÐниÑиализиÑÑем авÑоподÑÑÐ°Ð½Ð¾Ð²ÐºÑ Ð´Ð»Ñ Ð±ÑÑÑÑого заказа 218 if (name === 'ocb') { 219 setTimeout(initOcbCityAutocomplete, 400); 220 } 221 }; 222 223// ÐниÑиализаÑÐ¸Ñ Ð¿Ñи загÑÑзке AJAX-конÑенÑа 224 BX.addCustomEvent('onCompleteAction', function(eventdata) { 225 if (eventdata.action === 'loadForm' && eventdata.container) { 226 var $container = $(eventdata.container); 227 if ($container.closest('.ocb_frame').length || $container.find('.ocb_frame').length) { 228 setTimeout(initOcbCityAutocomplete, 500); 229 } 230 } 231 }); 232 233// ÐниÑиализаÑÐ¸Ñ Ð¿Ñи ÑÑпеÑной загÑÑзке ÑоÑÐ¼Ñ 234 BX.addCustomEvent('onAjaxSuccess', function(data, config) { 235 if (config && config.url && config.url.indexOf('oneclickbuy') !== -1) { 236 setTimeout(initOcbCityAutocomplete, 500); 237 } 238 }); 239 240// ÐÑзÑваем пÑи загÑÑзке ÑÑÑаниÑÑ (на ÑлÑÑай еÑли модалка Ñже оÑкÑÑÑа) 241 $(document).ready(function() { 242 setTimeout(initOcbCityAutocomplete, 1000); 243 }); 244 245 246 247 var shippingCitySearchXhr = null; 248 var shippingCitySearchTimer = null; 249 250 function normalizeShippingCity(value) { 251 return $.trim(value || '') 252 .toUpperCase() 253 .replace(/^Ð\.\s*/i, '') 254 .replace(/\s+/g, ' '); 255 } 256 257 function getShippingCityName($input) { 258 var storedName = $.trim($input.attr('data-city-name') || ''); 259 260 if (storedName) { 261 return normalizeShippingCity(storedName); 262 } 263 264 var value = $.trim($input.val() || ''); 265 266 if (value.indexOf(',') !== -1) { 267 return normalizeShippingCity(value.split(',')[0]); 268 } 269 270 return normalizeShippingCity(value); 271 } 272 273 function getShippingDeliveryText($input) { 274 var city = getShippingCityName($input); 275 var deliveryText = 'ÐеÑплаÑÐ½Ð°Ñ Ð´Ð¾ÑÑавка <br> Ð¾Ñ 30 000Ñ. до 5кг'; 276 277 if (city === 'СÐÐÐТ-ÐÐТÐÐ ÐУРÐ') { 278 deliveryText = $input.attr('data-default-text'); 279 } 280 281 if (city === 'ÐÐСÐÐÐ') { 282 deliveryText = 'ÐеÑплаÑÐ½Ð°Ñ Ð´Ð¾ÑÑавка <br> Ð¾Ñ 20 000Ñ. до 5кг'; 283 } 284 285 return deliveryText; 286 } 287 288 function getShippingCityTargetLine($input) { 289 var $target = $('.js-shipping-city-target').first(); 290 291 if ($input && $input.length) { 292 var $scoped = $input.closest('#bx-soa-total, .card-order-registr').find('.js-shipping-city-target').first(); 293 if ($scoped.length) { 294 $target = $scoped; 295 } 296 } 297 298 return $target.length ? $target.closest('.card-order-registr__line') : $(); 299 } 300 301 function toggleShippingCityTargetLine(show) { 302 var $line = getShippingCityTargetLine(); 303 304 if (!$line.length) { 305 return; 306 } 307 308 $line.addClass('akvastom-shipping-city-line'); 309 $line.toggleClass('akvastom-shipping-city-line--hidden', !show); 310 } 311 312 function updateAkvastomCityDependentUi() { 313 if ( 314 window.BX && 315 BX.Sale && 316 BX.Sale.OrderAjaxComponent && 317 typeof BX.Sale.OrderAjaxComponent.updateAkvastomCityDependentUi === 'function' 318 ) { 319 BX.Sale.OrderAjaxComponent.updateAkvastomCityDependentUi(); 320 } 321 } 322 323 function clearShippingCityTarget() { 324 if (!$('.js-shipping-city-target').length) { 325 return; 326 } 327 328 $('.js-shipping-city-target').html(''); 329 toggleShippingCityTargetLine(false); 330 } 331 332 function updateShippingCityTarget($input) { 333 if (!$('.js-shipping-city-target').length) { 334 return; 335 } 336 337 if (!$input || !$input.length || $input.attr('data-city-selected') !== '1') { 338 clearShippingCityTarget(); 339 return; 340 } 341 342 $('.js-shipping-city-target').html(getShippingDeliveryText($input)); 343 toggleShippingCityTargetLine(true); 344 } 345 346 function syncShippingCityTargetSidebar($input) { 347 if ($input && $input.length && $input.attr('data-city-selected') === '1') { 348 updateShippingCityTarget($input); 349 } else { 350 clearShippingCityTarget(); 351 } 352 } 353 354 var shippingCityOrderRefreshTimer = null; 355 356 function requestOrderRefreshAfterCityChange() { 357 if (!window.BX || !BX.Sale || !BX.Sale.OrderAjaxComponent) { 358 return; 359 } 360 361 var component = BX.Sale.OrderAjaxComponent; 362 363 clearTimeout(shippingCityOrderRefreshTimer); 364 shippingCityOrderRefreshTimer = setTimeout(function tryRefresh() { 365 if (component.BXFormPosting) { 366 shippingCityOrderRefreshTimer = setTimeout(tryRefresh, 200); 367 return; 368 } 369
370 if (component.markAkvastomCityChange) { 371 component.markAkvastomCityChange(); 372 } 373 if (component.syncAkvastomCityToOrderProps) { 374 component.syncAkvastomCityToOrderProps(); 375 } 376 if (component.saveAkvastomCityState) { 377 component.saveAkvastomCityState(); 378 } 379 380 component.deliveryCachedInfo = []; 381 component.initialized.delivery = false; 382 component.initialized.paySystem = false; 383 component.sendRequest(); 384 }, 350); 385 } 386 387 function setOrderLocationId(locationId) { 388 if (!locationId) { 389 return; 390 } 391 392 var cityFields = document.getElementById('bx-soa-city-fields'); 393 if (!cityFields) { 394 return; 395 } 396 397 var locHidden = cityFields.querySelector('.js-akvastom-location-id'); 398 var prevValue = locHidden ? String(locHidden.value || '') : ''; 399 var nextValue = String(locationId); 400 401 if (locHidden) { 402 locHidden.value = locationId; 403 } else { 404 cityFields.querySelectorAll('input[type="hidden"]').forEach(function (input) { 405 if (input.name && input.name.indexOf('ORDER_PROP') !== -1) { 406 input.value = locationId; 407 } 408 }); 409 } 410 411 var recentInput = document.querySelector('input[name="RECENT_DELIVERY_VALUE"]'); 412 if (recentInput) { 413 recentInput.value = locationId; 414 } 415 416 if (prevValue === nextValue) { 417 return; 418 } 419 420 requestOrderRefreshAfterCityChange(); 421 } 422 423 function selectShippingCityFromList($input, city) { 424 var $list = getShippingCitySuggestions($input); 425 var displayValue = city.label || city.name || ''; 426 var component = window.BX && BX.Sale ? BX.Sale.OrderAjaxComponent : null; 427 428 $input.val(displayValue); 429 $input.attr('data-city-name', city.name || ''); 430 $input.attr('data-location-id', city.id || ''); 431 $input.attr('data-city-selected', '1'); 432 hideShippingCitySuggestions($list, $input); 433 updateShippingCityTarget($input); 434 435 if (component && component.isAkvastomLayout && component.isAkvastomLayout()) { 436 component.akvastomCityState = { 437 locationId: String(city.id || ''), 438 cityName: city.name || '', 439 displayValue: displayValue, 440 selected: true 441 }; 442 if (component.markAkvastomCityChange) { 443 component.markAkvastomCityChange(); 444 } 445 } 446 447 setOrderLocationId(city.id); 448 updateAkvastomCityDependentUi(); 449 450 if (component) { 451 if (component.syncAkvastomCityToOrderProps) { 452 component.syncAkvastomCityToOrderProps(); 453 } 454 if (component.saveAkvastomCityState) { 455 component.saveAkvastomCityState(); 456 } 457 } 458 } 459
460 function invalidateShippingCitySelection($input) { 461 if ($input.attr('data-city-selected') !== '1') { 462 return; 463 } 464 465 $input.removeAttr('data-city-selected'); 466 $input.removeAttr('data-city-name'); 467 clearShippingCityTarget(); 468 updateAkvastomCityDependentUi(); 469 } 470 471 function getShippingCitySuggestions($input) { 472 var $wrap = $input.closest('.js-shipping-city-autocomplete'); 473 474 if (!$wrap.length) { 475 $input.wrap('<div class="input-type-1__autocomplete js-shipping-city-autocomplete"></div>'); 476 $wrap = $input.parent(); 477 } 478 479 var $list = $wrap.find('.js-shipping-city-suggestions'); 480 481 if (!$list.length) { 482 $list = $('<div class="js-shipping-city-suggestions shipping-city-suggestions" role="listbox" hidden></div>'); 483 $wrap.append($list); 484 } 485 486 return $list; 487 } 488 489 function getShippingCityWrap($input) { 490 return $input.closest('.js-shipping-city-autocomplete'); 491 } 492 493 function hideShippingCitySuggestions($list, $input) { 494 $list.attr('hidden', true).empty(); 495 $input.attr('aria-expanded', 'false'); 496 getShippingCityWrap($input).removeClass('is-open'); 497 } 498 499 function showShippingCitySuggestions($list, $input) { 500 $list.removeAttr('hidden'); 501 $input.attr('aria-expanded', 'true'); 502 getShippingCityWrap($input).addClass('is-open'); 503 } 504 505 function setActiveShippingCitySuggestion($list, index) { 506 var $items = $list.find('.shipping-city-suggestions__item'); 507 508 if (!$items.length) { 509 $list.data('activeIndex', -1); 510 return; 511 } 512 513 if (index < 0) { 514 index = $items.length - 1; 515 } 516 517 if (index >= $items.length) { 518 index = 0; 519 } 520 521 $list.data('activeIndex', index); 522 $items.removeClass('is-active').eq(index).addClass('is-active'); 523 } 524
525 function renderShippingCitySuggestions($input, cities) { 526 var $list = getShippingCitySuggestions($input); 527 528 $list.empty(); 529 $list.data('activeIndex', -1); 530 531 if (!cities.length) { 532 hideShippingCitySuggestions($list, $input); 533 return; 534 } 535 536 cities.forEach(function(city, index) { 537 var $item = $('<div>', { 538 class: 'shipping-city-suggestions__item', 539 role: 'option' 540 }); 541 542 $('<span>', { 543 class: 'shipping-city-suggestions__title', 544 text: city.name || '' 545 }).appendTo($item); 546 547 if (city.region) { 548 $('<span>', { 549 class: 'shipping-city-suggestions__region', 550 text: city.region 551 }).appendTo($item); 552 } 553 554 $item.on('mouseenter', function() { 555 setActiveShippingCitySuggestion($list, index); 556 }); 557 558 $item.on('mousedown', function(e) { 559 e.preventDefault(); 560 }); 561 562 $item.on('click', function() { 563 selectShippingCityFromList($input, city); 564 $input.trigger('focus'); 565 }); 566 567 $list.append($item); 568 }); 569 570 showShippingCitySuggestions($list, $input); 571 } 572 573 function requestShippingCitySuggestions($input, term) { 574 var $list = getShippingCitySuggestions($input); 575 576 if (shippingCitySearchXhr) { 577 shippingCitySearchXhr.abort(); 578 shippingCitySearchXhr = null; 579 } 580 581 if (term.length < 2) { 582 hideShippingCitySuggestions($list, $input); 583 return; 584 } 585 586 shippingCitySearchXhr = $.ajax({ 587 url: '/local/ajax/shipping_cities.php', 588 method: 'GET', 589 dataType: 'json', 590 data: { q: term }, 591 success: function(response) { 592 var cities = response && Array.isArray(response.cities) ? response.cities : []; 593 renderShippingCitySuggestions($input, cities); 594 }, 595 error: function() { 596 hideShippingCitySuggestions($list, $input); 597 }, 598 complete: function() { 599 shippingCitySearchXhr = null; 600 } 601 }); 602 } 603 604 function initShippingCityAutocomplete($input) { 605 var $list = getShippingCitySuggestions($input); 606 607 $input.on('keydown.shippingCitySuggestions', function(e) { 608 if ($list.is('[hidden]')) { 609 return; 610 } 611 612 var $items = $list.find('.shipping-city-suggestions__item'); 613 if (!$items.length) { 614 return; 615 } 616 617 var activeIndex = $list.data('activeIndex'); 618 if (typeof activeIndex !== 'number') { 619 activeIndex = -1; 620 } 621 622 if (e.key === 'ArrowDown') { 623 e.preventDefault();
624 setActiveShippingCitySuggestion($list, activeIndex + 1); 625 } else if (e.key === 'ArrowUp') { 626 e.preventDefault(); 627 setActiveShippingCitySuggestion($list, activeIndex - 1); 628 } else if (e.key === 'Enter' && activeIndex >= 0) { 629 e.preventDefault(); 630 $items.eq(activeIndex).trigger('click'); 631 } else if (e.key === 'Escape') { 632 hideShippingCitySuggestions($list, $input); 633 } 634 }); 635 636 $input.on('input', function() { 637 var term = $.trim($input.val()); 638 639 clearTimeout(shippingCitySearchTimer); 640 invalidateShippingCitySelection($input); 641 642 if (term.length < 2) { 643 hideShippingCitySuggestions($list, $input); 644 return; 645 } 646 647 shippingCitySearchTimer = setTimeout(function() { 648 requestShippingCitySuggestions($input, term); 649 }, 250); 650 }); 651 652 $input.on('blur', function() { 653 setTimeout(function() { 654 hideShippingCitySuggestions($list, $input); 655 }, 150); 656 }); 657 } 658 659 if ($('.js-shipping-city-target').length) { 660 clearShippingCityTarget(); 661 } 662 663 $('.js-shipping-city').each(function() { 664 initShippingCityAutocomplete($(this)); 665 }); 666 667 window.initShippingCityAutocomplete = initShippingCityAutocomplete; 668 window.updateShippingCityTarget = updateShippingCityTarget; 669 window.syncShippingCityTargetSidebar = syncShippingCityTargetSidebar; 670 window.updateAkvastomCityDependentUi = updateAkvastomCityDependentUi; 671 window.setOrderLocationId = setOrderLocationId; 672 window.requestOrderRefreshAfterCityChange = requestOrderRefreshAfterCityChange; 673});
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.