1/** 2 * @class app.product.compare 3 */ 4(function (app, $) { 5 var $cache = {}, 6 _currentCategory = "", 7 _isClearing = false, 8 MAX_ACTIVE = 5, 9 MAX_MOBILE = 2, 10 CI_PREFIX = "ci-"; 11 12 app.compareBreakpoints = { 13 md: '992px', 14 lg: ' 1099px', 15 xl: '1400px', 16 xxl: '1401px' 17 } 18 19 20 /** 21 * @private 22 * @function 23 * @description Verifies the number of elements in the compare container and updates it with sequential classes for ui targeting 24 */ 25 function refreshContainer() { 26 var recommendationElements = $('.js-recommendation'); 27 if (_isClearing) { return; } 28 29 var ac = $cache.compareContainer.find(".active").length; 30 31 if (ac < 2) { 32 $cache.compareButton.attr("disabled", "disabled"); 33 $cache.compareButton.addClass('hidden'); 34 35 if (window.matchMedia('(min-width: 1400px)').matches && recommendationElements.length) { 36 $cache.compareButton.siblings('#compare-recommended-items').removeClass('hidden'); 37 } 38 } else { 39 $cache.compareButton.removeAttr("disabled"); 40 $cache.compareButton.removeClass('hidden'); 41 $cache.compareButton.siblings('#compare-recommended-items').addClass('hidden'); 42 } 43 44 // update list with sequential classes for ui targeting 45 var compareItems = $cache.compareContainer.find('.compare-item'); 46 for( i=0; i < compareItems.length; i++ ){ 47 compareItems.removeClass('compare-item-' + i); 48 $(compareItems[i]).addClass('compare-item-' + i); 49 } 50 51 $cache.compareContainer.toggle(ac > 0); 52 53 } 54 /** 55 * @private 56 * @function 57 * @description Adds an item to the compare container and refreshes it 58 */ 59 function addToList(data) { 60 // get the first compare-item not currently active 61 var item = $cache.compareContainer.find(".compare-item").not(".active").first(); 62 var tile = $(data.cb).closest('.product-tile'); 63 if (item.length===0) { 64 if(tile.length > 0) { 65 tile.find(".compare-check")[0].checked = false; 66 } 67 window.alert(app.resources.COMPARE_ADD_FAIL) 68 return; 69 } // safety only 70 71 // if already added somehow, return 72 if ($("#"+CI_PREFIX+data.uuid).length > 0) { 73 return; 74 } 75 // set as active item 76 item.addClass("active") 77 .attr("id", CI_PREFIX + data.uuid) 78 .attr("data-itemid", data.itemid) 79 .attr("data-master-id", data.masterId); 80 81 // replace the item image 82 var itemImg = item.children("img.compareproduct").first(); 83 var src = null; 84 var alt = null; 85 86 if (typeof data.img == 'string') { 87 src = data.img; 88 alt = data.alt; 89 } else { 90 var $img = $(data.img); 91 src = $img.attr("src") ? $img.attr('src') : $img.attr('data-src'); 92 alt = $img.attr("alt"); 93 } 94 95 itemImg.attr({src : src, alt : alt}); 96 item.find('.product-name').text(data.title); 97 98 // refresh container state 99 refreshContainer(); 100 101 if (tile.length===0) { return; } 102 103 // ensure that the associated checkbox is checked 104 $('[id|="' + data.uuid + '"]').find(".compare-check").prop("checked", true); 105 } 106 /** 107 * @private 108 * @function 109 * description Removes an item from the compare container and refreshes it 110 */ 111 function removeFromList(itemId) { 112 var item = $("#compare-items-panel [data-master-id='" + itemId + "'], #compare-items-panel [data-itemid='" + itemId + "']"); 113 114 if (item.length === 0) return; 115 116 var tile = $(".grid-tile[data-itemid='" + item.attr('data-itemid') + "'], .grid-tile[data-itemid='" + item.attr('data-master-id') + "']"); 117 118 // replace the item image 119 var itemImg = item.children("img.compareproduct").first(); 120 itemImg.attr({src : app.urls.compareEmptyImage, alt : app.resources.EMPTY_IMG_ALT}); 121 122 // remove class, data and id from item 123 item.removeClass("active") 124 .removeAttr("id") 125 .removeAttr("data-itemid") 126 .data("itemid", ""); 127 128 // use clone to prevent image flash when removing item from list 129 item.find('.product-name').text(''); 130 var cloneItem = item.clone(); 131 item.remove(); 132 cloneItem.appendTo($cache.comparePanel); 133 refreshContainer(); 134 // ensure that the associated checkbox is not checked 135 if (tile.length === 0 ) { return; } 136 137 tile.find(".compare-check").prop("checked", false); 138 } 139 /** 140 * @private 141 * @function 142 * description Initializes the cache of compare container 143 */ 144 function initializeCache() { 145 $cache = { 146 primaryContent : $("#primary"), 147 compareContainer : $("#compare-items"), 148 compareButton : $("#compare-items-button"), 149 clearButton : $("#clear-compared-items"), 150 comparePanel : $("#compare-items-panel") 151 }; 152 } 153 /** 154 * @private 155 * @function 156 * @description Initializes the DOM-Object of the compare container 157 */ 158 function initializeDom() { 159 _currentCategory = $cache.compareContainer.data("category") || ""; 160 var active = $cache.compareContainer.find(".compare-item").filter(".active"); 161 active.each(function () { 162 var uuid = this.id.substr(CI_PREFIX.length); 163 var tile = $("#"+uuid); 164 if (tile.length === 0) { return; } 165 var cb = tile.find(".compare-check"); 166 167 if (cb.length === 0) return; 168 169 cb[0].checked = true; 170 }); 171 // set container state 172 refreshContainer(); 173 } 174 /** 175 * @private 176 * @function 177 * @description Initializes the events on the compare container 178 */ 179 function initializeEvents() { 180 // add event to buttons to remove products 181 $cache.primaryContent.on("click", ".compare-item-remove", function (e, async) { 182 var item = $(this).closest(".compare-item"); 183 var uuid = item[0].id.substr(CI_PREFIX.length); 184 var tile = $("#"+uuid); 185 var args = { 186 itemid : item.data("itemid"), 187 uuid : uuid, 188 cb : tile.length===0 ? null : tile.find(".compare-check"), 189 async : async 190 }; 191 app.product.compare.removeProduct(args); 192 refreshContainer(); 193 }); 194 195 // Button to go to compare page 196 $cache.primaryContent.on("click", "#compare-items-button", function () { 197 var compareItems = $(this).closest('.comparebar').find('#compare-items-panel > .compare-item'); 198 199 var path = app.urls.compareProducts + "?cid=" + _currentCategory; 200 for (let i = 0; i < compareItems.length; i++) { 201 let currentItem = $(compareItems[i]); 202 if(currentItem.attr('data-itemid') && i < 5){ 203 path += '&pid' + (i + 1) + '=' + currentItem.attr('data-itemid'); 204 } 205 } 206 207 window.location.href = path; 208 }); 209
210 // Button to clear all compared items 211 $cache.primaryContent.on("click", "#clear-compared-items", function () { 212 _isClearing = true; 213 $cache.compareContainer.hide() 214 .find(".active .compare-item-remove") 215 .trigger("click", [false]); 216 217 //set delay to allow for multiple items to be cleared without container flashing 218 window.setTimeout(function(){ 219 _isClearing = false; 220 }, 1000); 221 }); 222 } 223 224 /*************** app.product.compare public object ***************/ 225 app.product.compare = { 226 /** 227 * @function 228 * @description Cache, events and initialization 229 */ 230 init : function () { 231 initializeCache(); 232 initializeDom(); 233 initializeEvents(); 234 }, 235 initCache : initializeCache, 236 /** 237 * @function 238 * @description Adds product to the compare table 239 */ 240 addProduct : function (args) { 241 var items = $cache.compareContainer.find(".compare-item"); 242 var cb = $(args.cb); 243 var ac = items.filter(".active").length; 244 if(ac===MAX_ACTIVE) { 245 if (!window.confirm(app.resources.COMPARE_CONFIRMATION)) { 246 if (cb) cb[0].checked = false; 247 return; 248 } 249 250 // remove product using id 251 var item = items.first(); 252 253 // safety check only. should never occur. 254 if (item[0].id.indexOf(CI_PREFIX)!==0) { 255 if (cb) cb[0].checked = false; 256 window.alert(app.resources.COMPARE_ADD_FAIL); 257 return; 258 } 259 var uuid = item[0].id.substr(CI_PREFIX.length); 260 app.product.compare.removeProduct({ 261 itemid: item.data("itemid"), 262 uuid: uuid, 263 cb: $("#"+uuid).find(".compare-check"), 264 ajaxCall: false 265 }); 266 } 267 268 var device = null; 269 270 if (window.matchMedia('(max-width: ' + app.compareBreakpoints.md + ')').matches) { 271 device = { 272 // type: 'mobile', 273 numOfProds: 2 274 } 275 } else if (window.matchMedia('(max-width: ' + app.compareBreakpoints.lg + ')').matches) { 276 device = { 277 // type: 'tablet', 278 numOfProds: 3 279 } 280 } else if (window.matchMedia('(max-width: ' + app.compareBreakpoints.xl + ')').matches) { 281 device = { 282 // type: 'tabletBig', 283 numOfProds: 4 284 } 285 } 286 287 if(device && ac < device.numOfProds) { 288 app.ajax.getJson({ 289 url : app.urls.compareAdd, 290 data: { 'pid': args.itemid, 'category': _currentCategory }, 291 callback : function (response) { 292 if (!response || !response.success) { 293 // response failed. uncheck the checkbox return 294 if (cb) cb[0].checked = false; 295 window.alert(app.resources.COMPARE_ADD_FAIL); 296 return; 297 } 298 299 // item successfully stored in session, now add to list... 300 addToList(args); 301 } 302 }); 303 } else if(window.matchMedia('(min-width: ' + app.compareBreakpoints.xxl + ')').matches) { 304 app.ajax.getJson({ 305 url : app.urls.compareAdd, 306 data: { 'pid': args.itemid, 'category': _currentCategory }, 307 async: args.async, 308 callback : function (response) { 309 if (!response || !response.success) { 310 // response failed. uncheck the checkbox return 311 if (cb) cb[0].checked = false; 312 window.alert(app.resources.COMPARE_ADD_FAIL); 313 return; 314 } 315 316 // item successfully stored in session, now add to list... 317 addToList(args); 318 } 319 }); 320 } else { 321 var dialog = new $('.js-max-items').modal(); 322 var numOfProds = dialog.find('.number'); 323 324 if (device && numOfProds.length) { 325 numOfProds.text(device.numOfProds); 326 } 327 328 dialog.show(); 329 cb.attr('checked', false); 330 } 331 }, 332 /** 333 * @function 334 * @description Removes product from the compare table 335 */ 336 removeProduct : function (args) { 337 if (!args.itemid) { return; } 338 var cb = args.cb ? $(args.cb) : null; 339 var ajaxCall = args.ajaxCall ? $(args.ajaxCall) : true; 340 if(ajaxCall) { 341 app.ajax.getJson({ 342 url : app.util.appendParamsToUrl(app.urls.compareRemove, { 'pid' : args.itemid, 'category' : _currentCategory }), 343 callback : function (response) { 344 if (!response || !response.success) { 345 // response failed. uncheck the checkbox return 346 if (cb && cb.length > 0) { cb[0].checked = true; } 347 window.alert(app.resources.COMPARE_REMOVE_FAIL); 348 return; 349 } 350 351 // item successfully removed session, now remove from to list...
352 removeFromList(args.itemid); 353 } 354 }); 355 } else { 356 app.ajax.getJson({ 357 url : app.urls.compareRemove, 358 async: false, 359 data : { 'pid' : args.itemid, 'category' : _currentCategory }, 360 callback : function (response) { 361 if (!response || !response.success) { 362 // response failed. uncheck the checkbox return 363 if (cb && cb.length > 0) { cb[0].checked = true; } 364 window.alert(app.resources.COMPARE_REMOVE_FAIL); 365 return; 366 } 367 368 // item successfully removed session, now remove from to list... 369 removeFromList(args.itemid); 370 } 371 }); 372 } 373 374 } 375 }; 376 377}(window.app = window.app || {}, jQuery)); 378 379/** 380 * @class app.compare 381 */ 382(function (app, $) { 383 var $cache = {}; 384 var compareHeading = $('.compare-buttons h2'); 385 /** 386 * @private 387 * @function 388 * @description Initializes the cache on the compare table 389 */ 390 function initializeCache() { 391 $cache = { 392 compareTable : $("#compare-table"), 393 categoryList : $("#compare-category-list") 394 }; 395 } 396 /** 397 * @private 398 * @function 399 * @description Initializes the DOM on the product tile 400 */ 401 function initializeDom() { 402 app.product.tile.init(); 403 } 404 /** 405 * @private 406 * @function 407 * @description Binds the click events to the remove-link and quick-view button 408 */ 409 function initializeEvents() { 410 $cache.compareTable.on("click", ".remove-link", function (e) { 411 e.preventDefault(); 412 app.ajax.getJson({ 413 url : this.href, 414 callback : function (response) { 415 app.page.refresh(); 416 } 417 }); 418 }) 419 .on("click", ".open-quick-view", function (e) { 420 e.preventDefault(); 421 var form = $(this).closest("form"); 422 app.quickView.show({ 423 url:form.attr("action"), 424 source:"quickview", 425 data:form.serialize() 426 }); 427 }); 428 429 $cache.categoryList.on("change", function () { 430 $(this).closest("form").submit(); 431 }); 432 } 433 434 /*************** app.compare public object ***************/ 435 app.compare = { 436 /** 437 * @function 438 * @description Initializing of Cache, DOM and events 439 */ 440 init : function () { 441 triggerHeadingUpdate(); 442 initializeCache(); 443 initializeDom(); 444 initializeEvents(); 445 app.product.initAddToCart(); 446 } 447 }; 448 449 $(window).on('resize', function () { 450 triggerHeadingUpdate(); 451 }); 452 453 function triggerHeadingUpdate() { 454 if (!compareHeading.length) return; 455 456 var numberOfProdsElement = compareHeading.find('.allowed-num-of-prods'); 457 458 if (!numberOfProdsElement.length) return; 459 460 if (window.matchMedia('(max-width: ' + app.compareBreakpoints.md + ')').matches) numberOfProdsElement.text(2); 461 else if (window.matchMedia('(max-width: ' + app.compareBreakpoints.lg + ')').matches) numberOfProdsElement.text(3); 462 else if (window.matchMedia('(max-width: ' + app.compareBreakpoints.xl + ')').matches) numberOfProdsElement.text(4); 463 else if (window.matchMedia('(min-width: ' + app.compareBreakpoints.xxl + ')').matches) numberOfProdsElement.text(5); 464 }; 465}(window.app = window.app || {}, jQuery)); 466 467/** 468 * @class app.sendToFriend 469 */ 470(function (app, $) { 471 var $cache = {}, 472 initialized=false; 473 /** 474 * @private 475 * @function 476 * @description Initializes the events (preview, send, edit, cancel and close) on the send to friend form 477 */ 478 function initializeEvents() { 479 app.util.limitCharacters(); 480 if (initialized) {return; } 481 $cache.dialog.on("click", ".preview-button, .send-button, .edit-button", function (e) { 482 e.preventDefault(); 483 $cache.form.validate(); 484 if (!$cache.form.valid()) { 485 return false; 486 } 487 var requestType = $cache.form.find("#request-type"); 488 if (requestType.length>0) { 489 requestType.remove(); 490 } 491 $("<input/>").attr({id:"request-type", type:"hidden", name:$(this).attr("name"), value:$(this).attr("value")}).appendTo($cache.form); 492 var data = $cache.form.serialize(); 493 app.ajax.load({url:$cache.form.attr("action"), 494 data: data, 495 target: $cache.dialog, 496 callback: function() { 497 app.validator.init(); 498 app.util.limitCharacters(); 499 $cache.form = $("#send-to-friend-form"); 500 $(".ui-dialog-content").dialog("option", "position", "center"); 501 } 502 }); 503 }) 504 .on("click", ".cancel-button, .close-button", function (e) { 505 e.preventDefault(); 506 $cache.dialog.dialog("close"); 507 }); 508 initialized=true; 509 } 510 511 /*************** app.sendToFriend public object ***************/ 512 app.sendToFriend = { 513 init : function () { 514 $cache = { 515 form: $("#send-to-friend-form"), 516 dialog: $("#send-to-friend-dialog"), 517 pdpForm: $("form.pdpForm") 518 }; 519 initializeEvents(); 520 }, 521 522 /** 523 * @function 524 * @description 525 */ 526 initializeDialog : function (eventDelegate, eventTarget) { 527 $(eventDelegate).on("click", eventTarget, function (e) { 528 e.preventDefault(); 529 var dlg = app.dialog.create({target:$("#send-to-friend-dialog"), options:{ 530 width:800, 531 height:'auto', 532 title:this.title, 533 open:function() { 534 app.sendToFriend.init(); 535 app.validator.init(); 536 } 537 }}); 538 539 var data = app.util.getQueryStringParams($("form.pdpForm").serialize()); 540 if (data.cartAction) { 541 delete data.cartAction; 542 } 543 var url = app.util.appendParamsToUrl(this.href, data); 544 url = this.protocol + "//" + this.hostname + ((url.charAt(0)==="/") ? url : ("/"+url)); 545 app.ajax.load({ 546 url:app.util.ajaxUrl(url), 547 target:dlg, 548 callback: function () { 549 dlg.dialog("open"); // open after load to ensure dialog is centered 550 } 551 }); 552 }); 553 } 554 }; 555 556}(window.app = window.app || {}, jQuery));
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.