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