1;(function() { 2 'use strict'; 3 4 BX.namespace('BX.Sale.BasketComponent'); 5 6 BX.Sale.BasketComponent = { 7 maxItemsShowCount: 30, 8 precisionFactor: Math.pow(10, 6), 9 stickyHeaderOffset: 0, 10 11 duration: { 12 priceAnimation: 300, 13 filterTimer: 300 14 }, 15 16 ids: { 17 item: 'basket-item-', 18 quantity: 'basket-item-quantity-', 19 price: 'basket-item-price-', 20 sumPrice: 'basket-item-sum-price-', 21 sumPriceOld: 'basket-item-sum-price-old-', 22 sumPriceDiff: 'basket-item-sum-price-difference-', 23 itemHeightAligner: 'basket-item-height-aligner-', 24 total: 'basket-total-price', 25 basketRoot: 'basket-root', 26 itemListWrapper: 'basket-items-list-wrapper', 27 itemListContainer: 'basket-items-list-container', 28 itemList: 'basket-item-list', 29 itemListTable: 'basket-item-table', 30 itemListEmptyResult: 'basket-item-list-empty-result', 31 itemListOverlay: 'basket-items-list-overlay', 32 warning: 'basket-warning' 33 }, 34 35 initializePrimaryFields: function() 36 { 37 this.templates = {}; 38 this.nodes = {}; 39 40 /** Object of all basket items (itemId => itemArray) */ 41 this.items = {}; 42 43 /** Array of all basket items to show sorted by field SORT */ 44 this.sortedItems = []; 45 46 /** Array of basket items showed on screen */ 47 this.shownItems = []; 48 49 /** Array of basket items changed since last request */ 50 this.changedItems = []; 51 52 /** Array of basket items postponed by pool to edit */ 53 this.postponedItems = []; 54 55 /** Array of basket items with warnings */ 56 this.warningItems = []; 57 58 this.isMobile = BX.browser.IsMobile(); 59 this.isTouch = BX.hasClass(document.documentElement, 'bx-touch'); 60 61 this.lastAction = 'initialLoad'; 62 this.coupons = null; 63 64 this.imagePopup = null; 65 this.loadingScreen = null; 66 67 this.quantityDelay = null; 68 this.quantityTimer = null; 69 }, 70 71 init: function(parameters) 72 { 73 this.initializePrimaryFields(); 74 75 this.params = parameters.params || {}; 76 this.template = parameters.template || ''; 77 this.signedParamsString = parameters.signedParamsString || ''; 78 this.siteId = parameters.siteId || ''; 79 this.siteTemplateId = parameters.siteTemplateId || ''; 80 this.ajaxUrl = this.params.AJAX_PATH || ''; 81 this.templateFolder = parameters.templateFolder || ''; 82 83 this.useDynamicScroll = this.params.USE_DYNAMIC_SCROLL === 'Y'; 84 this.useItemsFilter = this.params.SHOW_FILTER === 'Y' && !this.isMobile; 85 86 this.initializeFilter(); 87 this.applyBasketResult(parameters.result); 88 this.initializeActionPool(); 89 90 if (this.useItemsFilter) 91 { 92 this.checkHeaderDisplay(); 93 this.bindHeaderEvents(); 94 } 95 96 this.initializeBasketItems(); 97 this.editTotal(); 98 this.editWarnings(); 99 100 this.adjustBasketWrapperHeight(); 101 this.getCacheNode(this.ids.basketRoot).style.opacity = 1; 102 103 this.bindInitialEvents(); 104 }, 105 106 getTemplate: function(templateName) 107 { 108 if (!this.templates.hasOwnProperty(templateName)) 109 { 110 var template = BX(templateName); 111 this.templates[templateName] = BX.type.isDomNode(template) ? template.innerHTML : ''; 112 } 113 114 return this.templates[templateName]; 115 }, 116 117 getCacheNode: function(id) 118 { 119 if (!this.nodes.hasOwnProperty(id)) 120 { 121 this.nodes[id] = BX(id); 122 } 123 124 return this.nodes[id]; 125 }, 126 127 getEntity: function(parent, entity, additionalFilter) 128 { 129 if (!parent || !entity) 130 return null; 131 132 additionalFilter = additionalFilter || ''; 133 134 return parent.querySelector(additionalFilter + '[data-entity="' + entity + '"]'); 135 }, 136 137 getEntities: function(parent, entity, additionalFilter) 138 { 139 if (!parent || !entity) 140 return {length: 0}; 141 142 additionalFilter = additionalFilter || ''; 143 144 return parent.querySelectorAll(additionalFilter + '[data-entity="' + entity + '"]'); 145 }, 146 147 bindInitialEvents: function() 148 { 149 this.bindWarningEvents(); 150 151 BX.bind(window, 'scroll', BX.proxy(this.checkStickyHeaders, this)); 152 BX.bind(window, 'scroll', BX.proxy(this.lazyLoad, this)); 153 154 BX.bind(window, 'resize', BX.throttle(this.checkStickyHeaders, 20, this)); 155 BX.bind(window, 'resize', BX.throttle(this.adjustBasketWrapperHeight, 20, this)); 156 }, 157 158 bindWarningEvents: function() 159 { 160 var showItemsNode = this.getEntity(BX(this.ids.warning), 'basket-items-warning-count'); 161 162 if (BX.type.isDomNode(showItemsNode)) 163 { 164 showItemsNode.style.display = ''; 165 BX.bind(showItemsNode, 'click', BX.delegate(function() {this.toggleFilter('warning');}, this)); 166 } 167 168 BX.bind( 169 this.getEntity(BX(this.ids.warning), 'basket-items-warning-notification-close'), 170 'click', 171 BX.proxy(this.removeAllWarnings, this) 172 ); 173 }, 174 175 toggleFilter: function(event) 176 { 177 var target = BX.type.isNotEmptyString(event) ? 178 this.getEntity( 179 this.getCacheNode(this.ids.itemListWrapper), 180 'basket-items-count', 181 '[data-filter="' + event + '"]' 182 ) 183 : BX.getEventTarget(event); 184 185 if (!BX.type.isDomNode(target) || BX.hasClass(target, 'active')) 186 return; 187 188 var entityName = target.getAttribute('data-filter'); 189 var entities = target.parentNode.querySelectorAll('[data-filter]'); 190 191 for (var i = 0; i < entities.length; i++) 192 { 193 if (entities[i].getAttribute('data-filter') === entityName) 194 { 195 BX.addClass(entities[i], 'active'); 196 } 197 else if (BX.hasClass(entities[i], 'active')) 198 { 199 BX.removeClass(entities[i], 'active'); 200 } 201 } 202 203 this.filter.showFilterByName(entityName); 204 }, 205 206 scrollToFirstItem: function() 207 { 208 var headerNode = this.getEntity(this.getCacheNode(this.ids.itemListWrapper), 'basket-items-list-header'); 209 210 if (BX.type.isDomNode(headerNode)) 211 { 212 var itemListTopPosition = BX.pos(this.getCacheNode(this.ids.itemListContainer)).top; 213 var headerBottomPosition = BX.pos(headerNode).bottom; 214 215 if (itemListTopPosition < headerBottomPosition) 216 { 217 window.scrollTo(0, itemListTopPosition - this.stickyHeaderOffset); 218 } 219 } 220 }, 221 222 showItemsOverlay: function() 223 {
224 var overlay = this.getCacheNode(this.ids.itemListOverlay); 225 226 if (BX.type.isDomNode(overlay)) 227 { 228 overlay.style.display = ''; 229 } 230 }, 231 232 hideItemsOverlay: function() 233 { 234 var overlay = this.getCacheNode(this.ids.itemListOverlay); 235 236 if (BX.type.isDomNode(overlay)) 237 { 238 overlay.style.display = 'none'; 239 } 240 }, 241 242 checkHeaderDisplay: function() 243 { 244 var header = this.getCacheNode(this.ids.itemListWrapper); 245 246 if (BX.type.isDomNode(header)) 247 { 248 BX.removeClass(header, 'basket-items-list-wrapper-light'); 249 } 250 }, 251 252 bindHeaderEvents: function() 253 { 254 var entities = this.getEntities(this.getCacheNode(this.ids.itemListWrapper), 'basket-items-count'); 255 256 for (var i = 0; i < entities.length; i++) 257 { 258 BX.bind(entities[i], 'click', BX.proxy(this.toggleFilter, this)); 259 } 260 }, 261 262 checkStickyHeaders: function() 263 { 264 if (this.isMobile) 265 return; 266 267 var node, position; 268 var border = 2, offset = 0; 269 var scrollTop = this.getDocumentScrollTop(); 270 var basketPosition = BX.pos(this.getCacheNode(this.ids.basketRoot)); 271 var basketScrolledToEnd = scrollTop + 200 >= basketPosition.bottom; 272 273 if (BX.util.in_array('top', this.params.TOTAL_BLOCK_DISPLAY)) 274 { 275 var totalBlockNode = this.getEntity(this.getCacheNode(this.ids.basketRoot), 'basket-total-block'); 276 if (BX.type.isDomNode(totalBlockNode)) 277 { 278 node = this.getEntity(totalBlockNode, 'basket-checkout-aligner'); 279 if (BX.type.isDomNode(node)) 280 { 281 position = BX.pos(totalBlockNode); 282 283 if (scrollTop >= position.top) 284 { 285 offset += node.clientHeight; 286 287 if (!BX.hasClass(node, 'basket-checkout-container-fixed')) 288 { 289 totalBlockNode.style.height = position.height + 'px'; 290 291 node.style.width = node.clientWidth + border + 'px'; 292 BX.addClass(node, 'basket-checkout-container-fixed'); 293 } 294 } 295 else if (BX.hasClass(node, 'basket-checkout-container-fixed')) 296 { 297 totalBlockNode.style.height = ''; 298 299 node.style.width = ''; 300 BX.removeClass(node, 'basket-checkout-container-fixed'); 301 } 302 303 if (basketScrolledToEnd) 304 { 305 if (!BX.hasClass(node, 'basket-checkout-container-fixed-hide')) 306 { 307 BX.addClass(node, 'basket-checkout-container-fixed-hide'); 308 } 309 } 310 else if (BX.hasClass(node, 'basket-checkout-container-fixed-hide')) 311 { 312 BX.removeClass(node, 'basket-checkout-container-fixed-hide'); 313 } 314 } 315 } 316 } 317 318 if (this.useItemsFilter) 319 { 320 var itemWrapperNode = this.getCacheNode(this.ids.itemListWrapper); 321 322 node = this.getEntity(itemWrapperNode, 'basket-items-list-header'); 323 if (BX.type.isDomNode(node)) 324 { 325 position = BX.pos(itemWrapperNode); 326 327 if ((scrollTop + offset >= position.top) && !basketScrolledToEnd) 328 { 329 if (!BX.hasClass(node, 'basket-items-list-header-fixed')) 330 { 331 node.style.width = node.clientWidth + border + 'px'; 332 333 itemWrapperNode.style.paddingTop = node.clientHeight + 'px'; 334 335 BX.addClass(node, 'basket-items-list-header-fixed'); 336 } 337 338 if (offset) 339 { 340 node.style.top = offset + 'px'; 341 } 342 343 offset += node.clientHeight; 344 } 345 else if (BX.hasClass(node, 'basket-items-list-header-fixed')) 346 { 347 itemWrapperNode.style.paddingTop = ''; 348 349 node.style.width = ''; 350 node.style.top = ''; 351 352 BX.removeClass(node, 'basket-items-list-header-fixed'); 353 } 354 } 355 } 356 357 var offsetChanged = this.stickyHeaderOffset === offset; 358 359 this.stickyHeaderOffset = offset; 360 361 if (offsetChanged && !basketScrolledToEnd) 362 { 363 this.adjustBasketWrapperHeight(); 364 } 365 }, 366 367 getDocumentScrollTop: function() 368 { 369 return window.scrollY 370 || window.pageYOffset 371 || document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0); 372 }, 373 374 lazyLoad: function() 375 { 376 var itemsNodePosition = BX.pos(this.getCacheNode(this.ids.itemListContainer)); 377 378 if (this.getDocumentScrollTop() + window.innerHeight >= itemsNodePosition.bottom - 400) 379 { 380 var itemIds = this.getItemsAfter(); 381 if (itemIds.length) 382 { 383 this.editBasketItems(itemIds); 384 } 385 } 386 }, 387 388 fireCustomEvents: function() 389 { 390 if (this.result.EVENT_ONCHANGE_ON_START === 'Y') 391 { 392 BX.onCustomEvent('OnBasketChange'); 393 } 394 395 if (this.params.HIDE_COUPON !== 'Y') 396 { 397 if (this.coupons !== null && this.coupons !== this.result.COUPON_LIST) 398 { 399 BX.onCustomEvent('OnCouponApply'); 400 } 401 402 this.coupons = this.result.COUPON_LIST; 403 } 404 }, 405 406 adjustBasketWrapperHeight: function() 407 { 408 var itemListContainer = this.getCacheNode(this.ids.itemListContainer), 409 itemList = this.getCacheNode(this.ids.itemList); 410 411 if (BX.type.isDomNode(itemListContainer) && BX.type.isDomNode(itemList)) 412 { 413 if (itemListContainer.clientHeight + this.stickyHeaderOffset > window.innerHeight) 414 { 415 itemListContainer.style.minHeight = 'calc(100vh - 15px - ' + this.stickyHeaderOffset + 'px)'; 416 itemList.style.minHeight = 'calc(100vh - 15px - ' + this.stickyHeaderOffset + 'px)'; 417 } 418 else 419 { 420 itemListContainer.style.minHeight = itemListContainer.clientHeight + 'px'; 421 itemList.style.minHeight = itemListContainer.clientHeight + 'px'; 422 } 423 } 424 }, 425 426 editTotal: function() 427 { 428 this.fillTotalBlocks(); 429 this.showItemsCount(); 430 this.showWarningItemsCount(); 431 this.showNotAvailableItemsCount(); 432 this.showDelayedItemsCount(); 433 }, 434 435 fillTotalBlocks: function() 436 { 437 var totalNodes = this.getEntities(this.getCacheNode(this.ids.basketRoot), 'basket-total-block'); 438 439 if (totalNodes && totalNodes.length) 440 { 441 var totalTemplate = this.getTemplate('basket-total-template'); 442 if (totalTemplate) 443 { 444 var totalRender = this.render(totalTemplate, this.result.TOTAL_RENDER_DATA); 445 446 for (var i in totalNodes) 447 { 448 if (totalNodes.hasOwnProperty(i) && BX.type.isDomNode(totalNodes[i])
448) 449 { 450 totalNodes[i].innerHTML = totalRender; 451 452 this.bindTotalEvents(totalNodes[i]); 453 } 454 } 455 } 456 } 457 458 this.checkStickyHeaders(); 459 }, 460 461 showItemsCount: function() 462 { 463 var itemCountNode = this.getEntity( 464 this.getCacheNode(this.ids.itemListWrapper), 465 'basket-items-count', 466 '[data-filter="all"]' 467 ); 468 469 if (BX.type.isDomNode(itemCountNode)) 470 { 471 itemCountNode.innerHTML = BX.message('SBB_IN_BASKET') + ' ' + this.result.BASKET_ITEMS_COUNT + ' ' + this.getGoodsMessage(this.result.BASKET_ITEMS_COUNT); 472 itemCountNode.style.display = ''; 473 } 474 }, 475 476 showSimilarCount: function(state) 477 { 478 var itemCountNode = this.getEntity( 479 this.getCacheNode(this.ids.itemListWrapper), 480 'basket-items-count', 481 '[data-filter="similar"]' 482 ); 483 484 if (BX.type.isDomNode(itemCountNode)) 485 { 486 if (state) 487 { 488 itemCountNode.innerHTML = this.sortedItems.length + ' ' 489 + this.getGoodsMessage(this.result.BASKET_ITEMS_COUNT, 'SBB_SIMILAR_ITEM'); 490 itemCountNode.style.display = ''; 491 } 492 else 493 { 494 itemCountNode.style.display = 'none'; 495 } 496 } 497 }, 498 499 showWarningItemsCount: function() 500 { 501 var itemCountNode = this.getEntity( 502 this.getCacheNode(this.ids.itemListWrapper), 503 'basket-items-count', 504 '[data-filter="warning"]' 505 ); 506 507 if (BX.type.isDomNode(itemCountNode)) 508 { 509 if (this.warningItems.length) 510 { 511 itemCountNode.innerHTML = this.warningItems.length + ' ' + BX.message('SBB_BASKET_ITEMS_WARNING'); 512 itemCountNode.style.display = ''; 513 } 514 else 515 { 516 itemCountNode.style.display = 'none'; 517 } 518 } 519 }, 520 521 showNotAvailableItemsCount: function() 522 { 523 var itemCountNode = this.getEntity( 524 this.getCacheNode(this.ids.itemListWrapper), 525 'basket-items-count', 526 '[data-filter="not-available"]' 527 ); 528 529 if (BX.type.isDomNode(itemCountNode)) 530 { 531 if (parseInt(this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT)) 532 { 533 itemCountNode.innerHTML = this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT + ' ' 534 + this.getGoodsMessage(this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT, 'SBB_NOT_AVAILABLE_ITEM'); 535 itemCountNode.style.display = ''; 536 } 537 else 538 { 539 itemCountNode.style.display = 'none'; 540 } 541 } 542 }, 543 544 showDelayedItemsCount: function() 545 { 546 var itemCountNode = this.getEntity( 547 this.getCacheNode(this.ids.itemListWrapper), 548 'basket-items-count', 549 '[data-filter="delayed"]' 550 ); 551 552 if (BX.type.isDomNode(itemCountNode)) 553 { 554 if (parseInt(this.result.DELAYED_BASKET_ITEMS_COUNT)) 555 { 556 itemCountNode.innerHTML = this.result.DELAYED_BASKET_ITEMS_COUNT + ' ' 557 + this.getGoodsMessage(this.result.DELAYED_BASKET_ITEMS_COUNT, 'SBB_DELAYED_ITEM'); 558 itemCountNode.style.display = ''; 559 } 560 else 561 { 562 itemCountNode.style.display = 'none'; 563 } 564 } 565 }, 566 567 getGoodsMessage: function(count, customMessage) 568 { 569 var mesCode; 570 var countReminder = (count > 10 && count < 20) ? 0 : count % 10; 571 572 if (countReminder === 1) 573 { 574 mesCode = customMessage || 'SBB_GOOD'; 575 } 576 else if (countReminder >= 2 && countReminder <= 4) 577 { 578 mesCode = customMessage ? customMessage + '_2' : 'SBB_GOOD_2'; 579 } 580 else 581 { 582 mesCode = customMessage ? customMessage + 'S' : 'SBB_GOODS'; 583 } 584 585 return BX.message(mesCode); 586 }, 587 588 bindTotalEvents: function(node) 589 { 590 if (!this.result.TOTAL_RENDER_DATA.DISABLE_CHECKOUT) 591 { 592 BX.bind(this.getEntity(node, 'basket-checkout-button'), 'click', BX.proxy(this.checkOutAction, this)); 593 } 594 595 // BX.bind(this.getEntity(node, 'basket-coupon-input'), 'change', BX.proxy(this.addCouponAction, this)); 596 // BX.bind(this.getEntity(node, 'basket-coupon-input'), 'paste', BX.proxy(this.pasteCouponAction, this)); 597 BX.bind(this.getEntity(node, 'basket-coupon-button'), 'click', BX.proxy(this.btnCouponAction, this)); 598 599 var couponNodes = this.getEntities(node, 'basket-coupon-delete'); 600 for (var i = 0, l = couponNodes.length; i < l; i++) 601 { 602 BX.bind(couponNodes[i], 'click', BX.proxy(this.removeCouponAction, this)); 603 } 604 605 }, 606 607 checkOutAction: function() 608 { 609 // custom --> 610 var path_to_order = this.params.PATH_TO_ORDER; 611 $('.jsOverlayBasketTotal').addClass('is-active'); 612 $('.jsOverlayBasketTotal').find('.catalog').addClass('is-loading'); 613 ym(86417006,'reachGoal', 'checkout-1'); 614 ym(86417006,'reachGoal', 'goal'); 615 setTimeout(function() { 616 document.location.href = path_to_order; 617 }, 500); 618 // <-- custom 619 620 // document.location.href = this.params.PATH_TO_ORDER; 621 }, 622 623 btnCouponAction: function(event) 624 { 625 var target = $('.cart-info__promo .input__field[data-entity="basket-coupon-input"]')[0]; 626 if (target && target.value) 627 { 628 this.actionPool.addCoupon(target.value); 629 target.disabled = true; 630 } 631 }, 632 633 addCouponAction: function(event) 634 { 635 var target = BX.getEventTarget(event); 636 if (target && target.value) 637 { 638 this.actionPool.addCoupon(target.value); 639 target.disabled = true; 640 } 641 }, 642 643 pasteCouponAction: function(event) 644 { 645 setTimeout(BX.delegate(function() { 646 this.addCouponAction(event); 647 }, this), 10); 648 }, 649 650 removeCouponAction: function() 651 { 652 var value = BX.proxy_context && BX.util.trim(BX.proxy_context.getAttribute('data-coupon')); 653 if (value) 654 { 655 this.actionPool.removeCoupon(value); 656 $.cookie('BITRIX_SM_retarget_promo', 'none') 657 } 658 }, 659 660 removeCustomCouponAction: function(node) 661 { 662 var value = node && BX.util.trim(node.getAttribute('data-coupon')); 663 if (value) { 664 this.actionPool.removeCoupon(value); 665 } 666 }, 667 668 initializeActionPool: function() 669 { 670 this.actionPool = new BX.Sale.BasketActionPool(this); 671 }, 672 673 initializeFilter: function() 674 { 675 this.filter = new BX.Sale.BasketFilter(this); 676 }, 677 678 /** 679 * Send ajax request with basket data and executes callback by action 680 */ 681 sendRequest: function(action, data) 682 { 683 this.lastAction = action; 684 685 if (this.lastAction === 'recalculateAjax') 686 { 687 // we use it to reload all items if applied discounts changed 688 data.lastAppliedDiscounts = BX.util.array_keys(this.result.FULL_DISCOUNT_LIST).join(','); 689 690 if (this.params.USE_ENHANCED_ECOMMERCE === 'Y') 691 { 692 this.checkAnalytics(data); 693 } 694 } 695 696 BX.ajax({ 697 method: 'POST', 698 dataType: 'json', 699 url: this.ajaxUrl, 700 data: this.getData(data), 701 onsuccess: BX.delegate(function(result) { 702 this.actionPool.doProcessing(false); 703 704 if (!BX.type.isPlainObject(result)) 705 return; 706 707 this.actionPool.setRefreshStatus(result.BASKET_REFRESHED); 708 709 if (result.RESTORED_BASKET_ITEMS) 710 { 711 this.restoreBasketItems(result.RESTORED_BASKET_ITEMS); 712 } 713 714 if (result.DELETED_BASKET_ITEMS) 715 { 716 this.deleteBasketItems(result.DELETED_BASKET_ITEMS, this.params.SHOW_RESTORE === 'Y'); 717 } 718 719 if (result.MERGED_BASKET_ITEMS) 720 { 721 this.deleteBasketItems(result.MERGED_BASKET_ITEMS, false, true); 722 } 723 724 this.applyBasketResult(result.BASKET_DATA); 725 this.editBasketItems(this.getItemsToEdit()); 726 this.editTotal(); 727 728 this.adjustBasketWrapperHeight(); 729 this.applyPriceAnimation(); 730 this.editWarnings(); 731 732 this.actionPool.switchTimer(); 733 734 if (this.isBasketIntegrated() && this.isBasketChanged()) 735 { 736 BX.Sale.OrderAjaxComponent.sendRequest(); 737 } 738 }, this), 739 onfailure: BX.delegate(function() { 740 this.actionPool.doProcessing(false); 741 }, this) 742 }); 743 }, 744 745 isBasketIntegrated: function() 746 { 747 return this.params.BASKET_WITH_ORDER_INTEGRATION === 'Y'; 748 }, 749 750 isBasketChanged: function() 751 { 752 return this.changedItems.length; 753 }, 754 755 addPriceAnimationData: function(nodeId, start, finish, currency) 756 { 757 if (!BX.type.isPlainObject(this.priceAnimationData)) 758 { 759 this.clearPriceAnimationData(); 760 } 761
762 this.priceAnimationData.start[nodeId] = parseFloat(start); 763 this.priceAnimationData.finish[nodeId] = parseFloat(finish); 764 this.priceAnimationData.currency[nodeId] = currency; 765 this.priceAnimationData.int[nodeId] = (parseFloat(start) === parseInt(start)) && (parseFloat(finish) === parseInt(finish)); 766 }, 767 768 clearPriceAnimationData: function() 769 { 770 this.priceAnimationData = { 771 start: {}, 772 finish: {}, 773 currency: {}, 774 int: {} 775 }; 776 }, 777 778 applyBasketResult: function(result) 779 { 780 this.changedItems = []; 781 this.clearPriceAnimationData(); 782 783 if (!BX.type.isPlainObject(result)) 784 { 785 return; 786 } 787 788 if (result.BASKET_ITEM_RENDER_DATA) 789 { 790 var i, newData; 791 792 for (i in result.BASKET_ITEM_RENDER_DATA) 793 { 794 if (result.BASKET_ITEM_RENDER_DATA.hasOwnProperty(i)) 795 { 796 newData = result.BASKET_ITEM_RENDER_DATA[i]; 797 newData.WARNINGS = this.checkBasketItemWarnings(newData, result.WARNING_MESSAGE_WITH_CODE); 798 799 if (this.items[newData.ID]) 800 { 801 if (JSON.stringify(this.items[newData.ID]) === JSON.stringify(newData)) 802 { 803 continue; 804 } 805 } 806 else 807 { 808 this.addSortedItem(newData.ID, true); 809 } 810 811 this.changedItems.push(newData.ID); 812 813 newData = this.checkBasketItemsAnimation(newData); 814 this.items[newData.ID] = newData; 815 } 816 } 817 818 this.changedItems = BX.util.array_unique(this.changedItems.concat(this.getChangedSimilarOffers())); 819 820 if (this.isBasketChanged()) 821 { 822 this.sortSortedItems(true); 823 } 824 } 825 826 if (result.TOTAL_RENDER_DATA) 827 { 828 result.TOTAL_RENDER_DATA = this.checkTotalAnimation(result.TOTAL_RENDER_DATA); 829 } 830 831 this.result = result; 832 }, 833 834 itemSortFunction: function(a, b) 835 { 836 if (!this.items.hasOwnProperty(a) || !this.items.hasOwnProperty(b)) 837 { 838 return 0; 839 } 840 841 return parseFloat(this.items[a].SORT) - parseFloat(this.items[b].SORT); 842 }, 843 844 getChangedSimilarOffers: function() 845 { 846 var changedSimilarOffers = []; 847 848 var otherSimilarItemsQuantity, totalSimilarItemsQuantity; 849 var hashMap = this.getHashMap(); 850 851 for (var hash in hashMap) 852 { 853 if (hashMap.hasOwnProperty(hash)) 854 { 855 if (hashMap[hash].length > 1) 856 { 857 for (var i = 0; i < hashMap[hash].length; i++) 858 { 859 otherSimilarItemsQuantity = 0; 860 totalSimilarItemsQuantity = 0; 861 862 for (var k = 0; k < hashMap[hash].length; k ++) 863 { 864 if (hashMap[hash][k] != hashMap[hash][i]) 865 { 866 otherSimilarItemsQuantity += parseFloat(this.items[hashMap[hash][k]].QUANTITY); 867 } 868 869 totalSimilarItemsQuantity += parseFloat(this.items[hashMap[hash][k]].QUANTITY); 870 } 871 872 if ( 873 !this.items[hashMap[hash][i]].HAS_SIMILAR_ITEMS 874 || this.items[hashMap[hash][i]].SIMILAR_ITEMS_QUANTITY != otherSimilarItemsQuantity 875 || this.items[hashMap[hash][i]].TOTAL_SIMILAR_ITEMS_QUANTITY != totalSimilarItemsQuantity 876 ) 877 { 878 changedSimilarOffers.push(hashMap[hash][i]); 879 880 this.items[hashMap[hash][i]].HAS_SIMILAR_ITEMS = true; 881 this.items[hashMap[hash][i]].SIMILAR_ITEMS_QUANTITY = otherSimilarItemsQuantity; 882 this.items[hashMap[hash][i]].TOTAL_SIMILAR_ITEMS_QUANTITY = totalSimilarItemsQuantity; 883 884 this.items[hashMap[hash][i]].ALL_AVAILABLE_QUANTITY = this.items[hashMap[hash][i]].AVAILABLE_QUANTITY; 885 this.items[hashMap[hash][i]].AVAILABLE_QUANTITY = this.items[hashMap[hash][i]].ALL_AVAILABLE_QUANTITY - otherSimilarItemsQuantity; 886 } 887 } 888 } 889 else if (hashMap[hash][0] && this.items[hashMap[hash][0]].HAS_SIMILAR_ITEMS) 890 { 891 changedSimilarOffers.push(hashMap[hash][0]); 892 893 delete this.items[hashMap[hash][0]].HAS_SIMILAR_ITEMS; 894 delete this.items[hashMap[hash][0]].SIMILAR_ITEMS_QUANTITY; 895 delete this.items[hashMap[hash][0]].TOTAL_SIMILAR_ITEMS_QUANTITY; 896 897 this.items[hashMap[hash][0]].AVAILABLE_QUANTITY = this.items[hashMap[hash][0]].ALL_AVAILABLE_QUANTITY; 898 delete this.items[hashMap[hash][0]].ALL_AVAILABLE_QUANTITY; 899 } 900 } 901 } 902 903 return changedSimilarOffers; 904 }, 905 906 getHashMap: function() 907 { 908 var hashMap = {}; 909 910 for (var id in this.items) 911 { 912 if (this.items.hasOwnProperty(id) && this.isItemAvailable(id)) 913 { 914 if (!hashMap.hasOwnProperty(this.items[id].HASH)) 915 { 916 hashMap[this.items[id].HASH] = []; 917 } 918 919 hashMap[this.items[id].HASH].push(id); 920 } 921 } 922 923 return hashMap; 924 }, 925 926 isItemAvailable: function(itemId) 927 { 928 var sortedItems = this.filter.isActive() ? this.filter.realSortedItems : this.sortedItems; 929 930 return !this.items[itemId].NOT_AVAILABLE 931 && !this.items[itemId].SHOW_RESTORE 932 && BX.util.in_array(itemId, sortedItems); 933 }, 934 935 checkTotalAnimation: function(totalData) 936 { 937 if (this.result && this.result.TOTAL_RENDER_DATA && parseFloat(this.result.TOTAL_RENDER_DATA.PRICE) > parseFloat(totalData.PRICE)) 938 { 939 totalData.PRICE_NEW = totalData.PRICE; 940 totalData.PRICE = this.result.TOTAL_RENDER_DATA.PRICE; 941 942 totalData.PRICE_FORMATED_NEW = totalData.PRICE_FORMATED; 943 totalData.PRICE_FORMATED = this.result.TOTAL_RENDER_DATA.PRICE_FORMATED; 944 945 this.addPriceAnimationData(this.ids.total, totalData.PRICE, totalData.PRICE_NEW, totalData.CURRENCY); 946 } 947 948 return totalData; 949 }, 950 951 checkBasketItemsAnimation: function(itemData) 952 { 953 var itemId = itemData.ID; 954 955 if (this.items[itemId]) 956 { 957 var quantityNode = BX(this.ids.quantity + itemId); 958 if ( 959 BX.type.isDomNode(quantityNode) 960 && !this.actionPool.isItemInPool(itemId) 961 && parseFloat(quantityNode.value) !== parseFloat(itemData.QUANTITY) 962 ) 963 { 964 itemData.QUANTITY_ANIMATION = true; 965 this.actionPool.clearLastActualQuantityPool(itemId); 966 } 967 968 if (parseFloat(this.items[itemId].PRICE) > parseFloat(itemData.PRICE)) 969 { 970 itemData.PRICE_NEW = itemData.PRICE; 971 itemData.PRICE = this.items[itemId].PRICE; 972 973 itemData.PRICE_FORMATED_NEW = itemData.PRICE_FORMATED; 974 itemData.PRICE_FORMATED = this.items[itemId].PRICE_FORMATED; 975 976 this.addPriceAnimationData(this.ids.price + itemId, itemData.PRICE, itemData.PRICE_NEW, itemData.CURRENCY); 977 } 978 979 if ( 980 BX.util.in_array('SUM', this.params.COLUMNS_LIST) 981 && parseFloat(this.items[itemId].SUM_PRICE) > parseFloat(itemData.SUM_PRICE) 982 && parseFloat(this.items[itemId].QUANTITY) === parseFloat(itemData.QUANTITY) 983 ) 984 { 985 itemData.SUM_PRICE_NEW = itemData.SUM_PRICE;
986 itemData.SUM_PRICE = this.items[itemId].SUM_PRICE; 987 988 itemData.SUM_PRICE_FORMATED_NEW = itemData.SUM_PRICE_FORMATED; 989 itemData.SUM_PRICE_FORMATED = this.items[itemId].SUM_PRICE_FORMATED; 990 991 this.addPriceAnimationData(this.ids.sumPrice + itemId, itemData.SUM_PRICE, itemData.SUM_PRICE_NEW, itemData.CURRENCY); 992 } 993 } 994 995 return itemData; 996 }, 997 998 getData: function(data) 999 { 1000 data = data || {}; 1001 1002 data[this.params.ACTION_VARIABLE] = this.lastAction; 1003 data.via_ajax = 'Y'; 1004 data.site_id = this.siteId; 1005 data.site_template_id = this.siteTemplateId; 1006 data.sessid = BX.bitrix_sessid(); 1007 data.template = this.template; 1008 data.signedParamsString = this.signedParamsString; 1009 1010 return data; 1011 }, 1012 1013 startLoader: function() 1014 { 1015 // if (!this.loadingScreen) 1016 // { 1017 // this.loadingScreen = new BX.PopupWindow('loading_screen', null, { 1018 // events: { 1019 // onAfterPopupShow: BX.delegate(function() { 1020 // BX.cleanNode(this.loadingScreen.popupContainer); 1021 // BX.removeClass(this.loadingScreen.popupContainer, 'popup-window'); 1022 // this.loadingScreen.popupContainer.appendChild( 1023 // BX.create('IMG', {props: {src: this.templateFolder + '/images/loader.gif'}}) 1024 // ); 1025 // this.loadingScreen.popupContainer.removeAttribute('style'); 1026 // this.loadingScreen.popupContainer.style.display = 'block'; 1027 // }, this) 1028 // } 1029 // }); 1030 // BX.addClass(this.loadingScreen.popupContainer, 'bx-step-opacity'); 1031 // } 1032 // 1033 // this.loadingScreen.show(); 1034 }, 1035 1036 /** 1037 * Hiding loader image with overlay. 1038 */ 1039 endLoader: function() 1040 { 1041 // if (this.loadingScreen && this.loadingScreen.isShown()) 1042 // { 1043 // this.loadingScreen.close(); 1044 // } 1045 }, 1046 1047 editWarnings: function() 1048 { 1049 this.editGeneralWarnings(); 1050 this.editBasketItemWarnings(); 1051 this.toggleWarningBlock(); 1052 this.showWarningItemsCount(); 1053 }, 1054 1055 editGeneralWarnings: function() 1056 { 1057 var warningsNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-general-warnings'); 1058 1059 if (BX.type.isDomNode(warningsNode)) 1060 { 1061 var generalWarningText = warningsNode.innerHTML; 1062 1063 if (this.result.WARNING_MESSAGE_WITH_CODE) 1064 { 1065 for (var code in this.result.WARNING_MESSAGE_WITH_CODE) 1066 { 1067 if (this.result.WARNING_MESSAGE_WITH_CODE.hasOwnProperty(code)) 1068 { 1069 if ( 1070 !this.items[code] 1071 && generalWarningText.indexOf(this.result.WARNING_MESSAGE_WITH_CODE[code]) === -1 1072 ) 1073 { 1074 generalWarningText += this.result.WARNING_MESSAGE_WITH_CODE[code] + '<br/>'; 1075 } 1076 } 1077 } 1078 } 1079 1080 if (generalWarningText) 1081 { 1082 warningsNode.innerHTML = generalWarningText; 1083 warningsNode.style.display = ''; 1084 } 1085 else 1086 { 1087 warningsNode.style.display = 'none'; 1088 warningsNode.innerHTML = ''; 1089 } 1090 } 1091 }, 1092 1093 editBasketItemWarnings: function() 1094 { 1095 var itemsWarningsNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-item-warnings'); 1096 1097 if (BX.type.isDomNode(itemsWarningsNode)) 1098 { 1099 if (this.warningItems.length) 1100 { 1101 var warningCount = this.getEntity(itemsWarningsNode, 'basket-items-warning-count'); 1102 if (BX.type.isDomNode(warningCount)) 1103 { 1104 warningCount.innerHTML = this.warningItems.length + ' ' + this.getGoodsMessage(this.warningItems.length); 1105 } 1106 1107 itemsWarningsNode.style.display = ''; 1108 } 1109 else if (itemsWarningsNode.style.display !== 'none') 1110 { 1111 itemsWarningsNode.style.display = 'none'; 1112 1113 if (this.filter.isActive()) 1114 { 1115 this.toggleFilter('all'); 1116 } 1117 } 1118 } 1119 }, 1120 1121 toggleWarningBlock: function() 1122 { 1123 var warningNode = this.getCacheNode(this.ids.warning); 1124 1125 if (BX.type.isDomNode(warningNode)) 1126 { 1127 var generalWarningNode = this.getEntity(warningNode, 'basket-general-warnings'); 1128 var itemsWarningsNode = this.getEntity(warningNode, 'basket-item-warnings'); 1129 1130 if ( 1131 (!BX.type.isDomNode(generalWarningNode) || generalWarningNode.style.display === 'none') 1132 && (!BX.type.isDomNode(itemsWarningsNode) || itemsWarningsNode.style.display === 'none') 1133 ) 1134 { 1135 warningNode.style.display = 'none'; 1136 } 1137 else 1138 { 1139 warningNode.style.display = ''; 1140 } 1141 } 1142 }, 1143 1144 checkBasketItemWarnings: function(itemData, warnings) 1145 { 1146 if (!itemData) 1147 return; 1148 1149 var itemWarnings; 1150 1151 if (this.items[itemData.ID] && this.lastAction === 'refreshAjax') 1152 { 1153 itemWarnings = this.items[itemData.ID].WARNINGS; 1154 } 1155 else 1156 {
1157 itemWarnings = []; 1158 } 1159 1160 if (BX.type.isArray(warnings[itemData.ID]) && warnings[itemData.ID].length) 1161 { 1162 for (var i in warnings[itemData.ID]) 1163 { 1164 if (warnings[itemData.ID].hasOwnProperty(i) && !BX.util.in_array(warnings[itemData.ID][i], itemWarnings)) 1165 { 1166 itemWarnings.push(warnings[itemData.ID][i]); 1167 } 1168 } 1169 } 1170 1171 if (itemWarnings.length) 1172 { 1173 if (!BX.util.in_array(itemData.ID, this.warningItems)) 1174 { 1175 this.warningItems.push(itemData.ID); 1176 } 1177 } 1178 else if (BX.util.in_array(itemData.ID, this.warningItems)) 1179 { 1180 this.warningItems.splice(BX.util.array_search(itemData.ID, this.warningItems), 1); 1181 } 1182 1183 return itemWarnings; 1184 }, 1185 1186 removeAllWarnings: function(event) 1187 { 1188 this.clearGeneralWarnings(); 1189 this.clearBasketItemsWarnings(); 1190 1191 this.editWarnings(); 1192 1193 event && event.preventDefault(); 1194 }, 1195 1196 clearGeneralWarnings: function() 1197 { 1198 this.result.WARNING_MESSAGE_WITH_CODE = {}; 1199 1200 var generalWarningNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-general-warnings'); 1201 1202 if (BX.type.isDomNode(generalWarningNode)) 1203 { 1204 generalWarningNode.innerHTML = ''; 1205 } 1206 }, 1207 1208 clearBasketItemsWarnings: function() 1209 { 1210 var itemsToEdit = []; 1211 1212 for (var i in this.warningItems) 1213 { 1214 if (this.warningItems.hasOwnProperty(i)) 1215 { 1216 this.items[this.warningItems[i]].WARNINGS = []; 1217 1218 if (this.isItemShown(this.warningItems[i])) 1219 { 1220 itemsToEdit.push(this.warningItems[i]); 1221 } 1222 } 1223 } 1224 1225 this.warningItems = []; 1226 this.editBasketItems(itemsToEdit); 1227 }, 1228 1229 isItemShown: function(itemId) 1230 { 1231 return BX.util.in_array(itemId, this.shownItems); 1232 }, 1233 1234 initializeBasketItems: function() 1235 { 1236 if (Object.keys(this.items).length === 0) 1237 return; 1238 1239 for (var i = 0; i < this.sortedItems.length; i++) 1240 { 1241 if (this.useDynamicScroll && this.shownItems.length >= this.maxItemsShowCount) 1242 { 1243 break; 1244 } 1245 1246 this.createBasketItem(this.sortedItems[i]); 1247 } 1248 }, 1249 1250 createBasketItem: function(itemId) 1251 { 1252 if (!this.items[itemId]) 1253 { 1254 return; 1255 } 1256 1257 var basketItemTemplate = this.getTemplate('basket-item-template'); 1258 if (basketItemTemplate) 1259 { 1260 var basketItemHtml = this.renderBasketItem(basketItemTemplate, this.items[itemId]); 1261 var sortIndex = BX.util.array_search(itemId, this.sortedItems); 1262 1263 if (this.shownItems.length && sortIndex >= 0) 1264 { 1265 if (sortIndex < BX.util.array_search(this.shownItems[0], this.sortedItems)) 1266 { 1267 // insert before 1268 BX(this.ids.item + this.shownItems[0]).insertAdjacentHTML('beforebegin', basketItemHtml); 1269 this.shownItems.unshift(itemId); 1270 } 1271 else if (sortIndex > BX.util.array_search(this.shownItems[this.shownItems.length - 1], this.sortedItems)) 1272 { 1273 // insert after 1274 BX(this.ids.item + this.shownItems[this.shownItems.length - 1]).insertAdjacentHTML('afterend', basketItemHtml); 1275 this.shownItems.push(itemId); 1276 } 1277 else 1278 { 1279 // insert between 1280 BX(this.ids.item + this.sortedItems[sortIndex + 1]).insertAdjacentHTML('beforebegin', basketItemHtml); 1281 this.shownItems.splice(sortIndex + 1, 0, itemId); 1282 } 1283 } 1284 else 1285 { 1286 this.getCacheNode(this.ids.itemListTable).insertAdjacentHTML('beforeend', basketItemHtml); 1287 this.shownItems.push(itemId); 1288 } 1289 1290 this.bindBasketItemEvents(this.items[itemId]); 1291 1292 if (this.filter.isActive()) 1293 { 1294 this.filter.highlightSearchMatch(this.items[itemId]); 1295 } 1296 } 1297 }, 1298 1299 getItemsToEdit: function() 1300 { 1301 var itemIds = []; 1302 1303 if (this.isBasketChanged()) 1304 { 1305 for (var i in this.changedItems) 1306 { 1307 if (this.changedItems.hasOwnProperty(i) && this.isItemShown(this.changedItems[i])) 1308 { 1309 itemIds.push(this.changedItems[i]); 1310 } 1311 } 1312 } 1313 1314 return itemIds; 1315 }, 1316 1317 getItemsAfter: function() 1318 { 1319 var itemIdsAfter = []; 1320 1321 if (this.useDynamicScroll) 1322 { 1323 var lastShownItemId = this.shownItems[this.shownItems.length - 1] || false; 1324 1325 if (lastShownItemId) 1326 { 1327 var i = 0; 1328 var index = BX.util.array_search(lastShownItemId, this.sortedItems); 1329 1330 while (this.sortedItems[++index] && i++ < this.maxItemsShowCount) 1331 { 1332 itemIdsAfter.push(this.sortedItems[index]); 1333 } 1334 } 1335 } 1336 1337 return itemIdsAfter; 1338 }, 1339 1340 editBasketItems: function(itemIds) 1341 { 1342 if (!itemIds || itemIds.length === 0) 1343 { 1344 return; 1345 } 1346 1347 var i, item; 1348 1349 for (i in itemIds) 1350 {
1351 if (!itemIds.hasOwnProperty(i) || !BX.type.isPlainObject(this.items[itemIds[i]])) 1352 { 1353 continue; 1354 } 1355 1356 item = this.items[itemIds[i]]; 1357 1358 if (this.actionPool.isItemInPool(item.ID)) 1359 { 1360 if (!BX.util.in_array(item.ID, this.postponedItems)) 1361 { 1362 this.postponedItems.push(item.ID); 1363 } 1364 1365 continue; 1366 } 1367 1368 if (BX.type.isDomNode(BX(this.ids.item + item.ID))) 1369 { 1370 this.redrawBasketItemNode(item.ID); 1371 this.applyQuantityAnimation(item.ID); 1372 } 1373 else 1374 { 1375 this.createBasketItem(item.ID); 1376 } 1377 } 1378 }, 1379 1380 editPostponedBasketItems: function() 1381 { 1382 if (!this.postponedItems.length) 1383 return; 1384 1385 var itemsToEdit = []; 1386 1387 for (var i in this.postponedItems) 1388 { 1389 if (this.postponedItems.hasOwnProperty(i) && this.isItemShown(this.postponedItems[i])) 1390 { 1391 itemsToEdit.push(this.postponedItems[i]); 1392 } 1393 } 1394 1395 this.postponedItems = []; 1396 this.editBasketItems(itemsToEdit); 1397 }, 1398 1399 applyQuantityAnimation: function(itemId) 1400 { 1401 var basketItemNode = BX(this.ids.item + itemId); 1402 1403 if (BX.type.isDomNode(basketItemNode) && this.items[itemId]) 1404 { 1405 if (this.items[itemId].QUANTITY_ANIMATION) 1406 { 1407 BX.addClass(BX(this.ids.quantity + itemId), 'basket-updated'); 1408 } 1409 } 1410 }, 1411 1412 applyPriceAnimation: function() 1413 { 1414 if (!this.priceAnimationData || Object.keys(this.priceAnimationData.start).length === 0) 1415 return; 1416 1417 var animationData = this.priceAnimationData, 1418 nodeCache = {}; 1419 1420 new BX.easing({ 1421 duration: this.params.USE_PRICE_ANIMATION === 'Y' ? this.duration.priceAnimation : 1, 1422 start: animationData.start, 1423 finish: animationData.finish, 1424 transition: BX.easing.makeEaseOut(BX.easing.transitions.quad), 1425 step: BX.delegate(function(state){ 1426 for (var nodeId in animationData.start) 1427 { 1428 if (animationData.start.hasOwnProperty(nodeId)) 1429 { 1430 if (!nodeCache[nodeId]) 1431 { 1432 if (nodeId === this.ids.total) 1433 { 1434 nodeCache[nodeId] = this.getEntities(this.getCacheNode(this.ids.basketRoot), this.ids.total); 1435 } 1436 else 1437 { 1438 var node = BX(nodeId); 1439 nodeCache[nodeId] = node ? [node] : []; 1440 } 1441 } 1442 1443 if (!animationData.int[nodeId]) 1444 { 1445 // fix price blinking 1446 state[nodeId] = (state[nodeId] + (state[nodeId] % 1000) / 1000).toFixed(5); 1447 } 1448 1449 for (var i = 0; i < nodeCache[nodeId].length; i++) 1450 { 1451 nodeCache[nodeId][i].innerHTML = this.getFormatPrice(state[nodeId], animationData.currency[nodeId]); 1452 } 1453 } 1454 } 1455 }, this), 1456 complete: BX.delegate(function() { 1457 var nodeId, formattedPrice, itemId, type; 1458 1459 for (nodeId in animationData.start) 1460 { 1461 if (animationData.start.hasOwnProperty(nodeId)) 1462 { 1463 formattedPrice = this.getFormatPrice(animationData.finish[nodeId], animationData.currency[nodeId]); 1464 1465 for (var i = 0; i < nodeCache[nodeId].length; i++) 1466 { 1467 nodeCache[nodeId][i].innerHTML = formattedPrice; 1468 } 1469 1470 if (nodeId.indexOf(this.ids.sumPrice) !== -1) 1471 { 1472 type = 'SUM_PRICE'; 1473 itemId = nodeId.substr(this.ids.sumPrice.length); 1474 } 1475 else if (nodeId.indexOf(this.ids.price) !== -1) 1476 { 1477 type = 'PRICE'; 1478 itemId = nodeId.substr(this.ids.price.length); 1479 } 1480 else if (nodeId.indexOf(this.ids.total) !== -1) 1481 { 1482 type = 'TOTAL'; 1483 itemId = ''; 1484 } 1485 else 1486 { 1487 itemId = ''; 1488 type = ''; 1489 } 1490 1491 if (BX.type.isNotEmptyString(type)) 1492 { 1493 if (itemId) 1494 { 1495 this.items[itemId][type] = animationData.finish[nodeId]; 1496 delete this.items[itemId][type + '_NEW']; 1497 this.items[itemId][type + '_FORMATED'] = formattedPrice; 1498 delete this.items[itemId][type + '_FORMATED_NEW']; 1499 } 1500 else if (type === 'TOTAL') 1501 { 1502 this.result.TOTAL_RENDER_DATA.PRICE = animationData.finish[nodeId]; 1503 delete this.result.TOTAL_RENDER_DATA.PRICE_NEW; 1504 this.result.TOTAL_RENDER_DATA.PRICE_FORMATED = formattedPrice; 1505 delete this.result.TOTAL_RENDER_DATA.PRICE_FORMATED_NEW; 1506 } 1507 } 1508 } 1509 } 1510 1511 this.filter.highlightFoundItems(); 1512 }, this) 1513 }).animate(); 1514 }, 1515 1516 getFormatPrice: function(price, currency) 1517 { 1518 // return BX.Currency.currencyFormat(price, currency, true); 1519 return new Intl.NumberFormat('ru-RU').format(price) + " ₽"; 1520 return BX.Currency.currencyFormat(price, currency, true); 1521 }, 1522 1523 deleteBasketItems: function(items, restore, final) 1524 { 1525 if (!items || !items.length) 1526 { 1527 return; 1528 } 1529 1530 for (var i in items) 1531 { 1532 if (items.hasOwnProperty(i)) 1533 { 1534 this.deleteBasketItem(items[i], restore, final); 1535 } 1536 } 1537 }, 1538 1539 deleteBasketItem: function(itemId, restore, final) 1540 { 1541 // delete not available item with no chance to restore 1542 if (this.items[itemId].NOT_AVAILABLE && restore) 1543 { 1544 restore = false;
1545 final = true; 1546 } 1547 1548 if (restore) 1549 { 1550 this.items[itemId].SHOW_RESTORE = true; 1551 this.items[itemId].SHOW_LOADING = false; 1552 this.redrawBasketItemNode(itemId); 1553 } 1554 else 1555 { 1556 this.changeShownItem(itemId); 1557 BX.remove(BX(this.ids.item + itemId)); 1558 } 1559 1560 if (final) 1561 { 1562 this.changeSortedItem(itemId, false, true); 1563 this.changeShownItem(itemId, false, true); 1564 } 1565 }, 1566 1567 addSortedItem: function(itemId, all) 1568 { 1569 this.sortedItems.push(itemId.toString()); 1570 1571 if (all && this.filter.isActive()) 1572 { 1573 this.filter.realSortedItems.push(itemId.toString()); 1574 } 1575 }, 1576 1577 changeSortedItem: function(itemId, newItemId, all) 1578 { 1579 var index = BX.util.array_search(itemId, this.sortedItems); 1580 1581 if (index >= 0) 1582 { 1583 if (newItemId) 1584 { 1585 this.sortedItems.splice(index, 1, newItemId.toString()); 1586 } 1587 else 1588 { 1589 this.sortedItems.splice(index, 1); 1590 } 1591 } 1592 1593 if (all && this.filter.isActive()) 1594 { 1595 index = BX.util.array_search(itemId, this.filter.realSortedItems); 1596 1597 if (index >= 0) 1598 { 1599 if (newItemId) 1600 { 1601 this.filter.realSortedItems.splice(index, 1, newItemId.toString()); 1602 } 1603 else 1604 { 1605 this.filter.realSortedItems.splice(index, 1); 1606 } 1607 } 1608 } 1609 }, 1610 1611 sortSortedItems: function(all) 1612 { 1613 this.sortedItems.sort(BX.proxy(this.itemSortFunction, this)); 1614 1615 if (all && this.filter.isActive()) 1616 { 1617 this.filter.realSortedItems.sort(BX.proxy(this.itemSortFunction, this)); 1618 } 1619 }, 1620 1621 changeShownItem: function(itemId, newItemId, all) 1622 { 1623 var index = BX.util.array_search(itemId, this.shownItems); 1624 1625 if (index >= 0) 1626 { 1627 if (newItemId) 1628 { 1629 this.shownItems.splice(index, 1, newItemId.toString()); 1630 } 1631 else 1632 { 1633 this.shownItems.splice(index, 1); 1634 } 1635 } 1636 1637 if (all && this.filter.isActive()) 1638 { 1639 index = BX.util.array_search(itemId, this.filter.realShownItems); 1640 1641 if (index >= 0) 1642 { 1643 if (newItemId) 1644 { 1645 this.filter.realShownItems.splice(index, 1, newItemId.toString()); 1646 } 1647 else 1648 { 1649 this.filter.realShownItems.splice(index, 1); 1650 } 1651 } 1652 } 1653 }, 1654 1655 redrawBasketItemNode: function(itemId) 1656 { 1657 var basketItemNode = BX(this.ids.item + itemId); 1658 1659 if (!this.items[itemId] || !BX.type.isDomNode(basketItemNode)) 1660 return; 1661 1662 var basketItemTemplate = this.getTemplate('basket-item-template'); 1663 if (basketItemTemplate) 1664 { 1665 var nodeAligner = BX(this.ids.itemHeightAligner + itemId), 1666 oldHeight; 1667 1668 if (BX.type.isDomNode(nodeAligner)) 1669 { 1670 oldHeight = nodeAligner.clientHeight; 1671 } 1672 1673 var basketItemHtml = this.renderBasketItem(basketItemTemplate, this.items[itemId]); 1674 basketItemNode.insertAdjacentHTML('beforebegin', basketItemHtml); 1675 BX.remove(basketItemNode); 1676 1677 if (oldHeight) 1678 { 1679 nodeAligner = BX(this.ids.itemHeightAligner + itemId); 1680 1681 if (BX.type.isDomNode(nodeAligner) && nodeAligner.clientHeight < oldHeight) 1682 { 1683 nodeAligner.style.minHeight = oldHeight + 'px'; 1684 setTimeout(function(){nodeAligner.style.minHeight = '0px';}, 1); 1685 } 1686 } 1687 1688 this.bindBasketItemEvents(this.items[itemId]); 1689 1690 if (this.filter.isActive()) 1691 { 1692 this.filter.highlightSearchMatch(this.items[itemId]); 1693 } 1694 } 1695 }, 1696 1697 restoreBasketItems: function(items) 1698 { 1699 if (!items || Object.keys(items).length === 0) 1700 { 1701 return; 1702 } 1703 1704 var oldItemId, newItemId, basketItemNode; 1705 1706 for (oldItemId in items) 1707 { 1708 if (items.hasOwnProperty(oldItemId)) 1709 { 1710 newItemId = items[oldItemId]; 1711 1712 if (this.isItemShown(oldItemId)) 1713 { 1714 this.changeShownItem(oldItemId, newItemId, true); 1715 1716 basketItemNode = BX(this.ids.item + oldItemId); 1717 if (BX.type.isDomNode(basketItemNode)) 1718 { 1719 basketItemNode.id = this.ids.item + newItemId; 1720 basketItemNode.setAttribute('data-id', newItemId); 1721 } 1722 } 1723 1724 this.changeSortedItem(oldItemId, false, true); 1725 } 1726 } 1727 }, 1728 1729 bindBasketItemEvents: function(itemData) 1730 { 1731 if (!itemData) 1732 return; 1733 1734 var itemNode = BX(this.ids.item + itemData.ID); 1735 if (BX.type.isDomNode(itemNode)) 1736 { 1737 this.bindQuantityEvents(itemNode, itemData); 1738 this.bindSkuEvents(itemNode, itemData); 1739 this.bindImageEvents(itemNode, itemData); 1740 this.bindActionEvents(itemNode, itemData); 1741 this.bindRestoreAction(itemNode, itemData); 1742 this.bindItemWarningEvents(itemNode, itemData); 1743 } 1744 }, 1745 1746 bindQuantityEvents: function(node, data) 1747 { 1748 if (!node || !data || !this.isItemAvailable(data.ID)) 1749 return; 1750 1751 var entity; 1752 1753 var block = this.getEntity(node, 'basket-item-quantity-block'); 1754 if (block) 1755 { 1756 var startEventName = this.isTouch ? 'touchstart' : 'mousedown'; 1757 var endEventName = this.isTouch ? 'touchend' : 'mouseup'; 1758 1759 entity = this.getEntity(block, 'basket-item-quantity-minus'); 1760 BX.bind(entity, startEventName, BX.proxy(this.startQuantityInterval, this)); 1761 BX.bind(entity, endEventName, BX.proxy(this.clearQuantityInterval, this)); 1762 BX.bind(entity, 'mouseout', BX.proxy(this.clearQuantityInterval, this)); 1763 BX.bind(entity, 'click', BX.proxy(this.quantityMinus, this)); 1764 1765 entity = this.getEntity(block, 'basket-item-quantity-plus'); 1766 BX.bind(entity, startEventName, BX.proxy(this.startQuantityInterval, this)); 1767 BX.bind(entity, endEventName, BX.proxy(this.clearQuantityInterval, this)); 1768 BX.bind(entity, 'mouseout', BX.proxy(this.clearQuantityInterval, this)); 1769 BX.bind(entity, 'click', BX.proxy(this.quantityPlus, this)); 1770 1771 entity = this.getEntity(block, 'basket-item-quantity-field'); 1772 BX.bind(entity, 'change', BX.proxy(this.quantityChange, this)); 1773 } 1774 }, 1775 1776 startQuantityInterval: function() 1777 { 1778 var target = BX.proxy_context; 1779 var func = target.getAttribute('data-entity') === 'basket-item-quantity-minus' 1780 ? BX.proxy(this.quantityMinus, this) 1781 : BX.proxy(this.quantityPlus, this); 1782 1783 this.quantityDelay = setTimeout( 1784 BX.delegate(function() { 1785 this.quantityTimer = setInterval(function(){func(target);}, 150); 1786 }, this), 1787 300 1788 ); 1789 }, 1790 1791 clearQuantityInterval: function() 1792 { 1793 clearTimeout(this.quantityDelay); 1794 clearInterval(this.quantityTimer); 1795 }, 1796 1797 quantityPlus: function(target) 1798 { 1799 if (!BX.type.isDomNode(target)) 1800 { 1801 target = BX.proxy_context; 1802 this.clearQuantityInterval(); 1803 } 1804 1805 var itemData = this.getItemDataByTarget(target); 1806 if (itemData) 1807 { 1808 var quantityField = BX(this.ids.quantity + itemData.ID); 1809 var isQuantityFloat = this.isQuantityFloat(itemData); 1810 1811 var currentQuantity = isQuantityFloat ? parseFloat(quantityField.value) : Math.round(quantityField.value); 1812 var measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO); 1813 1814 var quantity = parseFloat((currentQuantity + measureRatio).toFixed(5)); 1815 quantity = this.getCorrectQuantity(itemData, quantity); 1816 1817 this.setQuantity(itemData, quantity); 1818 } 1819 }, 1820 1821 quantityMinus: function(target) 1822 { 1823 target = BX.type.isDomNode(target) ? target : BX.proxy_context; 1824 1825 var itemData = this.getItemDataByTarget(target); 1826 if (itemData) 1827 { 1828 var quantityField = BX(this.ids.quantity + itemData.ID); 1829 var isQuantityFloat = this.isQuantityFloat(itemData); 1830 1831 var currentQuantity = isQuantityFloat ? parseFloat(quantityField.value) : Math.round(quantityField.value); 1832 var measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO); 1833 1834 var quantity = parseFloat((currentQuantity - measureRatio).toFixed(5)); 1835 quantity = this.getCorrectQuantity(itemData, quantity); 1836 1837 this.setQuantity(itemData, quantity); 1838 } 1839 }, 1840 1841 quantityChange: function() 1842 { 1843 var itemData = this.getItemDataByTarget(BX.proxy_context); 1844 if (itemData) 1845 { 1846 var quantityField, quantity; 1847 1848 quantityField = BX(this.ids.quantity + itemData.ID); 1849 quantity = this.getCorrectQuantity(itemData, quantityField.value); 1850 1851 this.setQuantity(itemData, quantity); 1852 } 1853 }, 1854 1855 isQuantityFloat: function(item) 1856 { 1857 return this.params.QUANTITY_FLOAT === 'Y' || (parseInt(item.MEASURE_RATIO) !== parseFloat(item.MEASURE_RATIO)); 1858 }, 1859 1860 getCorrectQuantity: function(itemData, quantity) 1861 { 1862 var isQuantityFloat = this.isQuantityFloat(itemData), 1863 measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO), 1864 availableQuantity = 0; 1865 1866 quantity = (isQuantityFloat ? parseFloat(quantity) : parseInt(quantity, 10)) || 0; 1867 if (quantity < 0) 1868 { 1869 quantity = 0; 1870 } 1871 1872 if (measureRatio > 0 && quantity < measureRatio) 1873 { 1874 quantity = measureRatio; 1875 } 1876 1877 if (itemData.CHECK_MAX_QUANTITY === 'Y') 1878 { 1879 availableQuantity = isQuantityFloat ? parseFloat(itemData.AVAILABLE_QUANTITY) : parseInt(itemData.AVAILABLE_QUANTITY); 1880 if (availableQuantity > 0 && quantity > availableQuantity) 1881 { 1882 quantity = availableQuantity; 1883 } 1884 } 1885 1886 var reminder = (quantity / measureRatio - ((quantity / measureRatio).toFixed(0))).toFixed(5), 1887 remain; 1888 1889 if (parseFloat(reminder) === 0) 1890 { 1891 return quantity; 1892 } 1893 1894 if (measureRatio !== 0 && measureRatio !== 1) 1895 { 1896 remain = (quantity * this.precisionFactor) % (measureRatio * this.precisionFactor) / this.precisionFactor; 1897 1898 if (measureRatio > 0 && remain > 0) 1899 { 1900 if ( 1901 remain >= measureRatio / 2 1902 && ( 1903 availableQuantity === 0 1904 || (quantity + measureRatio - remain) <= availableQuantity 1905 ) 1906 ) 1907 { 1908 quantity += (measureRatio - remain); 1909 } 1910 else 1911 { 1912 quantity -= remain; 1913 } 1914 } 1915 } 1916 1917 quantity = isQuantityFloat ? parseFloat(quantity) : parseInt(quantity, 10); 1918 1919 return quantity; 1920 }, 1921 1922 setQuantity: function(itemData, quantity) 1923 { 1924 var quantityField = BX(this.ids.quantity + itemData.ID), 1925 currentQuantity; 1926 1927 if (quantityField) 1928 { 1929 quantity = parseFloat(quantity); 1930 currentQuantity = parseFloat(quantityField.getAttribute('data-value')); 1931 1932 quantityField.value = quantity; 1933 1934 if (parseFloat(itemData.QUANTITY) !== parseFloat(quantity)) 1935 { 1936 this.animatePriceByQuantity(itemData, quantity); 1937 this.actionPool.changeQuantity(itemData.ID, quantity, currentQuantity); 1938 } 1939 } 1940 }, 1941 1942 animatePriceByQuantity: function(itemData, quantity) 1943 { 1944 var priceNode = BX(this.ids.sumPrice + itemData.ID); 1945 if (!BX.type.isDomNode(priceNode)) 1946 return; 1947 1948 var quantityMultiplier = quantity / parseFloat(itemData.MEASURE_RATIO); 1949 1950 var startPrice = parseFloat(itemData.SUM_PRICE), 1951 finalPrice = parseFloat(itemData.PRICE) * quantityMultiplier, 1952 isInt = parseInt(startPrice) === parseFloat(startPrice) 1953 && parseInt(finalPrice) === parseFloat(finalPrice); 1954 1955 if (startPrice !== finalPrice) 1956 { 1957 this.items[itemData.ID].QUANTITY = quantity;
1958 this.items[itemData.ID].SUM_PRICE = finalPrice; 1959 1960 new BX.easing({ 1961 duration: this.params.USE_PRICE_ANIMATION === 'Y' ? this.duration.priceAnimation : 1, 1962 start: {price: startPrice}, 1963 finish: {price: finalPrice}, 1964 transition: BX.easing.makeEaseOut(BX.easing.transitions.quad), 1965 step: BX.delegate(function(state){ 1966 if (!isInt) 1967 { 1968 // fix price blinking 1969 state.price = (state.price + (state.price % 1000) / 1000).toFixed(5); 1970 } 1971 1972 priceNode.innerHTML = this.getFormatPrice(state.price, itemData.CURRENCY); 1973 }, this), 1974 complete: BX.delegate(function() { 1975 var node, price; 1976 1977 priceNode.innerHTML = this.getFormatPrice(finalPrice, itemData.CURRENCY); 1978 1979 node = BX(this.ids.sumPriceOld + itemData.ID); 1980 if (BX.type.isDomNode(node)) 1981 { 1982 price = parseFloat(itemData.FULL_PRICE) * quantityMultiplier; 1983 node.innerHTML = this.getFormatPrice(price, itemData.CURRENCY); 1984 } 1985 1986 node = BX(this.ids.sumPriceDiff + itemData.ID); 1987 if (BX.type.isDomNode(node)) 1988 { 1989 price = parseFloat(itemData.DISCOUNT_PRICE) * quantityMultiplier; 1990 node.innerHTML = this.getFormatPrice(price, itemData.CURRENCY); 1991 } 1992 }, this) 1993 }).animate(); 1994 } 1995 }, 1996 1997 getItemDataByTarget: function(target) 1998 { 1999 var data = false; 2000 var id; 2001 2002 var itemNode = BX.findParent(target, {attrs: {'data-entity': 'basket-item'}}); 2003 if (itemNode) 2004 { 2005 id = itemNode.getAttribute('data-id'); 2006 data = this.items[id]; 2007 } 2008 2009 return data; 2010 }, 2011 2012 bindSkuEvents: function(node, data) 2013 { 2014 if (!node || !data) 2015 return; 2016 2017 var blocks = this.getEntities(node, 'basket-item-sku-block'); 2018 var blockEntities, i, l, ii, ll; 2019 2020 for (i = 0, l = blocks.length; i < l; i++) 2021 { 2022 blockEntities = this.getEntities(blocks[i], 'basket-item-sku-field'); 2023 2024 for (ii = 0, ll = blockEntities.length; ii < ll; ii++) 2025 { 2026 BX.bind(blockEntities[ii], 'click', BX.proxy(this.changeSku, this)); 2027 } 2028 } 2029 }, 2030 2031 changeSku: function() 2032 { 2033 var i, l; 2034 2035 var target = BX.proxy_context; 2036 2037 if (BX.hasClass(target, 'selected')) 2038 return; 2039 2040 var itemData = this.getItemDataByTarget(target); 2041 if (itemData) 2042 { 2043 var basketItemNode = BX(this.ids.item + itemData.ID); 2044 if (basketItemNode) 2045 { 2046 var currentSkuListNodes = this.getEntities(target.parentNode, 'basket-item-sku-field'); 2047 for (i = 0, l = currentSkuListNodes.length; i < l; i++) 2048 { 2049 if (currentSkuListNodes[i].isEqualNode(target)) 2050 { 2051 BX.addClass(currentSkuListNodes[i], 'selected'); 2052 } 2053 else 2054 { 2055 BX.removeClass(currentSkuListNodes[i], 'selected'); 2056 } 2057 } 2058 2059 this.actionPool.changeSku( 2060 itemData.ID, 2061 this.getSkuPropertyValues(basketItemNode), 2062 this.getInitialSkuPropertyValues(basketItemNode) 2063 ); 2064 } 2065 } 2066 }, 2067 2068 getSkuPropertyValues: function(basketItemNode) 2069 { 2070 var propertyValues = {}; 2071 2072 var propNodes = this.getEntities(basketItemNode, 'basket-item-sku-field', '.selected'); 2073 for (var i = 0, l = propNodes.length; i < l; i++) 2074 { 2075 propertyValues[propNodes[i].getAttribute('data-property')] = BX.util.htmlspecialcharsback(propNodes[i].getAttribute('data-value-id')); 2076 } 2077 2078 return propertyValues; 2079 }, 2080 2081 getInitialSkuPropertyValues: function(basketItemNode) 2082 { 2083 var propertyValues = {}; 2084 2085 var propNodes = this.getEntities(basketItemNode, 'basket-item-sku-field', '[data-initial="true"]'); 2086 for (var i = 0, l = propNodes.length; i < l; i++) 2087 { 2088 propertyValues[propNodes[i].getAttribute('data-property')] = BX.util.htmlspecialcharsback(propNodes[i].getAttribute('data-value-id')); 2089 } 2090 2091 return propertyValues; 2092 }, 2093 2094 bindImageEvents: function(node, data) 2095 { 2096 if (!node || !data) 2097 return; 2098 2099 var images = node.querySelectorAll('.basket-item-custom-block-photo-item'); 2100 for (var i = 0, l = images.length; i < l; i++) 2101 { 2102 BX.bind(images[i], 'click', BX.proxy(this.showPropertyImagePopup, this)); 2103 } 2104 }, 2105 2106 showPropertyImagePopup: function() 2107 { 2108 var target, propertyCode, imageIndex, item, imageSrc, i; 2109 2110 target = BX.proxy_context; 2111 item = this.getItemDataByTarget(target); 2112 2113 propertyCode = target.getAttribute('data-column-property-code'); 2114 imageIndex = target.getAttribute('data-image-index'); 2115 2116 if (item && item.COLUMN_LIST) 2117 { 2118 for (i in item.COLUMN_LIST) 2119 { 2120 if ( 2121 item.COLUMN_LIST.hasOwnProperty(i) 2122 && item.COLUMN_LIST[i].CODE === propertyCode 2123 && item.COLUMN_LIST[i].VALUE[imageIndex] 2124 ) 2125 { 2126 imageSrc = item.COLUMN_LIST[i].VALUE[imageIndex].IMAGE_SRC_ORIGINAL; 2127 break; 2128 } 2129 } 2130 } 2131 2132 if (!imageSrc) 2133 { 2134 return; 2135 } 2136 2137 if (this.imagePopup) 2138 { 2139 this.imagePopup.destroy(); 2140 } 2141 2142 var imageId = 'bx-soa-image-popup-content'; 2143 var that = this; 2144 2145 this.imagePopup = new BX.PopupWindow('bx-soa-image-popup', null, { 2146 lightShadow: true, 2147 offsetTop: 0, 2148 offsetLeft: 0, 2149 closeIcon: {top: '3px', right: '10px'}, 2150 autoHide: true, 2151 bindOptions: {position: 'bottom'}, 2152 closeByEsc: true, 2153 zIndex: 100, 2154 events: { 2155 onPopupShow: function() { 2156 BX.create('IMG', { 2157 props: {src: imageSrc}, 2158 events: { 2159 load: function() { 2160 var content = BX(imageId); 2161 if (content) 2162 { 2163 var windowSize = BX.GetWindowInnerSize(), 2164 ratio = that.isMobile ? 0.5 : 0.9, 2165 contentHeight, contentWidth; 2166 2167 BX.cleanNode(content); 2168 content.appendChild(this); 2169 2170 contentHeight = content.offsetHeight; 2171 contentWidth = content.offsetWidth; 2172 2173 if (contentHeight >
2173 windowSize.innerHeight * ratio) 2174 { 2175 content.style.height = windowSize.innerHeight * ratio + 'px'; 2176 content.style.width = contentWidth * (windowSize.innerHeight * ratio / contentHeight) + 'px'; 2177 contentHeight = content.offsetHeight; 2178 contentWidth = content.offsetWidth; 2179 } 2180 2181 if (contentWidth > windowSize.innerWidth * ratio) 2182 { 2183 content.style.width = windowSize.innerWidth * ratio + 'px'; 2184 content.style.height = contentHeight * (windowSize.innerWidth * ratio / contentWidth) + 'px'; 2185 } 2186 2187 content.style.height = content.offsetHeight + 'px'; 2188 content.style.width = content.offsetWidth + 'px'; 2189 2190 that.imagePopup.adjustPosition(); 2191 } 2192 } 2193 } 2194 }); 2195 }, 2196 onPopupClose: function() { 2197 this.destroy(); 2198 } 2199 }, 2200 content: BX.create('DIV', {props: {id: imageId}}) 2201 }); 2202 this.imagePopup.show(); 2203 }, 2204 2205 bindActionEvents: function(node, data) 2206 { 2207 if (!node || !data) 2208 return; 2209 2210 var entity; 2211 2212 if (BX.util.in_array('DELETE', this.params.COLUMNS_LIST)) 2213 { 2214 entity = this.getEntities(node, 'basket-item-delete'); 2215 for (var i = 0, l = entity.length; i < l; i++) 2216 { 2217 BX.bind(entity[i], 'click', BX.proxy(this.deleteAction, this)); 2218 } 2219 } 2220 2221 if (BX.util.in_array('DELAY', this.params.COLUMNS_LIST)) 2222 { 2223 entity = this.getEntity(node, 'basket-item-add-delayed'); 2224 BX.bind(entity, 'click', BX.proxy(this.addDelayedAction, this)); 2225 } 2226 2227 entity = this.getEntity(node, 'basket-item-remove-delayed'); 2228 BX.bind(entity, 'click', BX.proxy(this.removeDelayedAction, this)); 2229 2230 entity = this.getEntity(node, 'basket-item-merge-sku-link'); 2231 BX.bind(entity, 'click', BX.proxy(this.mergeAction, this)); 2232 2233 entity = this.getEntity(node, 'basket-item-show-similar-link'); 2234 BX.bind(entity, 'click', BX.delegate(function() {this.toggleFilter('similar');}, this)); 2235 }, 2236 2237 deleteAction: function() 2238 { 2239 var itemData = this.getItemDataByTarget(BX.proxy_context); 2240 if (itemData) 2241 { 2242 this.actionPool.deleteItem(itemData.ID); 2243 2244 this.items[itemData.ID].SHOW_LOADING = true; 2245 2246 if (this.params.SHOW_RESTORE === 'Y' && this.isItemAvailable(itemData.ID)) 2247 { 2248 this.items[itemData.ID].SHOW_RESTORE = true; 2249 // ym(56006068, 'reachGoal', 'analitycCartProductDelete'); 2250 // gtag('event', 'click', {'event_category': 'button', 'event_label': 'analitycCartProductDelete'}); 2251 } 2252 2253 this.redrawBasketItemNode(itemData.ID); 2254 } 2255 }, 2256 2257 addDelayedAction: function() 2258 { 2259 var itemData = this.getItemDataByTarget(BX.proxy_context); 2260 if (itemData) 2261 { 2262 this.actionPool.addDelayed(itemData.ID); 2263 2264 this.items[itemData.ID].SHOW_LOADING = true; 2265 this.redrawBasketItemNode(itemData.ID); 2266 } 2267 }, 2268 2269 removeDelayedAction: function() 2270 { 2271 var itemData = this.getItemDataByTarget(BX.proxy_context); 2272 if (itemData) 2273 { 2274 this.actionPool.removeDelayed(itemData.ID); 2275 2276 this.items[itemData.ID].SHOW_LOADING = true; 2277 this.redrawBasketItemNode(itemData.ID); 2278 } 2279 }, 2280 2281 mergeAction: function() 2282 { 2283 var itemData = this.getItemDataByTarget(BX.proxy_context); 2284 if (itemData) 2285 { 2286 this.actionPool.mergeSku(itemData.ID); 2287 } 2288 }, 2289 2290 bindRestoreAction: function(node, itemData) 2291 { 2292 if (!node || !itemData || this.params.SHOW_RESTORE !== 'Y') 2293 return; 2294 2295 BX.bind( 2296 this.getEntity(node, 'basket-item-restore-button'), 2297 'click', 2298 BX.delegate(function() { 2299 this.actionPool.restoreItem(itemData.ID, { 2300 PRODUCT_ID: itemData.PRODUCT_ID, 2301 QUANTITY: itemData.QUANTITY, 2302 PROPS: itemData.PROPS_ALL, 2303 SORT: itemData.SORT, 2304 MODULE: itemData.MODULE, 2305 PRODUCT_PROVIDER_CLASS: itemData.PRODUCT_PROVIDER_CLASS 2306 }); 2307 2308 this.items[itemData.ID].SHOW_RESTORE = false; 2309 this.items[itemData.ID].SHOW_LOADING = true; 2310 2311 // ym(56006068, 'reachGoal', 'analitycCartProductRestore'); 2312 // gtag('event', 'click', {'event_category': 'button', 'event_label': 'analitycCartProductRestore'}); 2313 2314 this.redrawBasketItemNode(itemData.ID); 2315 }, this) 2316 ); 2317 BX.bind( 2318 this.getEntity(node, 'basket-item-close-restore-button'), 2319 'click', 2320 BX.delegate(function() { 2321 this.deleteBasketItem(itemData.ID, false, true); 2322 }, this) 2323 ); 2324 }, 2325 2326 bindItemWarningEvents: function(node, data) 2327 { 2328 if (!node || !data) 2329 return; 2330 2331 BX.bind( 2332 this.getEntity(BX(this.ids.item + data.ID), 'basket-item-warning-close'), 2333 'click', 2334 BX.proxy(this.closeItemWarnings, this) 2335 ); 2336 }, 2337 2338 closeItemWarnings: function() 2339 { 2340 var target = BX.proxy_context; 2341 2342 if (BX.type.isDomNode(target)) 2343 { 2344 var itemData = this.getItemDataByTarget(target); 2345 2346 this.items[itemData.ID].WARNINGS = []; 2347 this.warningItems.splice(BX.util.array_search(itemData.ID, this.warningItems), 1); 2348 2349 this.redrawBasketItemNode(itemData.ID); 2350 this.editWarnings(); 2351 } 2352 }, 2353 2354 renderBasketItem: function(template, data) 2355 { 2356 var clonedData = BX.clone(data); 2357 2358 if (BX.type.isPlainObject(clonedData)) 2359 { 2360 clonedData.USE_FILTER = this.useItemsFilter 2361 && !this.filter.currentFilter.similarHash.length; 2362 } 2363 2364 return Mustache.render(template, clonedData); 2365 }, 2366 2367 render: function(template, data) 2368 { 2369 return Mustache.render(template, data); 2370 }, 2371 2372 checkAnalytics: function(data) 2373 { 2374 if (!data || !data.basket) 2375 return; 2376 2377 var itemId, itemsDiff = {}; 2378 2379 for (var i in data.basket) 2380 { 2381 if (data.basket.hasOwnProperty(i)) 2382 { 2383 if (i.indexOf('QUANTITY_') >= 0) 2384 { 2385 itemId = i.substr(9); 2386 2387 if (this.items[itemId]) 2388 { 2389 itemsDiff[itemId] = parseFloat(data.basket[i]) - parseFloat(BX(this.ids.quantity + itemId).getAttribute('data-value')); 2390 } 2391 } 2392 else if (i.indexOf('DELETE_') >= 0) 2393 { 2394 itemId = i.substr(7); 2395 2396 if (this.items[itemId]) 2397 {
2398 itemsDiff[itemId] = -parseFloat(this.items[itemId].QUANTITY); 2399 } 2400 } 2401 else if (i.indexOf('RESTORE_') >= 0) 2402 { 2403 itemId = i.substr(8); 2404 2405 if (this.items[itemId]) 2406 { 2407 itemsDiff[itemId] = parseFloat(this.items[itemId].QUANTITY); 2408 } 2409 } 2410 } 2411 } 2412 2413 this.setAnalyticsDataLayer(itemsDiff); 2414 }, 2415 2416 setAnalyticsDataLayer: function(itemsDiff) 2417 { 2418 if (!itemsDiff || Object.keys(itemsDiff).length === 0) 2419 return; 2420 2421 window[this.params.DATA_LAYER_NAME] = window[this.params.DATA_LAYER_NAME] || []; 2422 2423 var plus = [], minus = []; 2424 2425 for (var itemId in itemsDiff) 2426 { 2427 if (itemsDiff.hasOwnProperty(itemId)) 2428 { 2429 if (itemsDiff[itemId] > 0) 2430 { 2431 plus.push(this.getItemAnalyticsInfo(itemId, itemsDiff[itemId])); 2432 } 2433 else if (itemsDiff[itemId] < 0) 2434 { 2435 minus.push(this.getItemAnalyticsInfo(itemId, itemsDiff[itemId])); 2436 } 2437 } 2438 } 2439 2440 if (plus.length) 2441 { 2442 window[this.params.DATA_LAYER_NAME].push({ 2443 event: 'addToCart', 2444 ecommerce: { 2445 currencyCode: this.items[itemId].CURRENCY || '', 2446 add: { 2447 products: plus 2448 } 2449 } 2450 }); 2451 } 2452 2453 if (minus.length) 2454 { 2455 window[this.params.DATA_LAYER_NAME].push({ 2456 event: 'removeFromCart', 2457 ecommerce: { 2458 currencyCode: this.items[itemId].CURRENCY || '', 2459 remove: { 2460 products: minus 2461 } 2462 } 2463 }); 2464 } 2465 }, 2466 2467 getItemAnalyticsInfo: function(itemId, diff) 2468 { 2469 if (!this.items[itemId]) 2470 return {}; 2471 2472 var brand = (this.items[itemId].BRAND || '').split(', ').join('/'); 2473 var variants = []; 2474 2475 var selectedSku = this.getEntities(BX(this.ids.item + itemId), 'basket-item-sku-field', '.selected'); 2476 for (var i = 0, l = selectedSku.length; i < l; i++) 2477 { 2478 variants.push(selectedSku[i].getAttribute('data-sku-name')); 2479 } 2480 2481 return { 2482 'name': this.items[itemId].NAME || '', 2483 'id': this.items[itemId].PRODUCT_ID || '', 2484 'price': this.items[itemId].PRICE || 0, 2485 'brand': brand, 2486 'variant': variants.join('/'), 2487 'quantity': Math.abs(diff) 2488 }; 2489 } 2490 }; 2491})();
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.