PageSourceSearch

https://www.jbl.com.ph/on/demandware.static/Sites-JB-APAC-NCOM-Sit…/js/app/006_productcompare.js

js jbl.com.ph collected 2026-09-25 22:49:18 UTC 15,819 bytes, 556 lines download raw bytes

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.