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