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