PageSourceSearch

https://www.jacksonholechamber.com/includes/public/managed/v_c8155…/common/virtuals/js/shared_footer.js

js jacksonholechamber.com collected 2026-09-24 17:34:53 UTC 9,164 bytes, 297 lines download raw bytes

1// This file will be run in the footer on every page.
2// It should be used for content that relates
3// to your site as a whole, it should not be used for
4// plugin-specific js
5
6require(["jquery", "site_gtm", "plugins_common_custom_ui_watcher", "sv_load!plugins_dynamic_content", "domReady!"], function($, gtm, UIWatcher, dynamic) {
7	gtm.update();
8
9	// SEM tracking
10	var uiEvents = new UIWatcher({}, $, document);
11	uiEvents.on("change-page", handlePageChange);
12	uiEvents.on("view-change", handleFilterChange);
13	uiEvents.on("sort-change", handleFilterChange);
14	uiEvents.on("value-change", handleFilterChange);
15	uiEvents.on("toggle-show-more", handleShowMoreToggle);
16	uiEvents.on("scroll-into-view", handleScrollIntoView);
17	uiEvents.on("item-click", handleItemClick);
18	uiEvents.on("map-pin-click", handleMapPinClick);
19	uiEvents.on("tripbuilder", handleTripbuilder);
20	uiEvents.on("qv-tripbuilder", handleTripbuilder);
21	uiEvents.on("quick-view", handleQuickview);
22
23	// tracking handlers
24	function handleTripbuilder(payload){
25		var event = payload.eventContext,
26			widget = payload.widgetContext;
27		var eventCatName = widget.name;
28		switch (event.detailType) {
29				case "listings":
30					eventCatName = "Listings";
31					break;
32				case "events":
33					eventCatName = "Events";
34					break;
35				case "offers":
36					eventCatName = "Coupons";
37					break;
38				default:
39					eventCatName = widget.name;
40		}
41		var data = {
42			eventCategory: eventCatName,
43			eventAction: event.name +" - "+ event.value,
44			eventLabel: event.refTitle,
45			ot: event.type,
46			ltxt: event.displayText,
47			nonInteraction: false
48		}
49		if (data.eventCategory && data.eventAction && data.eventLabel)
50			gtm.sendEvents({tClient: data});
51	}
52	
53	function handleQuickview(payload){
54		var event = payload.eventContext,
55			widget = payload.widgetContext;
56		var eventCatName = widget.name;
57		switch (event.detailType) {
58				case "listings":
59					eventCatName = "Listings";
60					break;
61				case "events":
62					eventCatName = "Events";
63					break;
64				case "offers":
65					eventCatName = "Coupons";
66					break;
67				default:
68					eventCatName = widget.name;
69		}
70		var data = {
71			eventCategory: eventCatName,
72			eventAction: event.linkTo,
73			eventLabel: event.refTitle,
74			ot: event.type,
75			ltxt: event.displayText,
76			nonInteraction: false
77		}
78		if (data.eventCategory && data.eventAction && data.eventLabel)
79			gtm.sendEvents({tClient: data});
80	}
81
82	function handleScrollIntoView(payload){
83		var event = payload.eventContext,
84			widget = payload.widgetContext;
85		var data = {
86			eventCategory: widget.name,
87			eventAction: event.name,
88			eventLabel: "Widget - "+widget.name,
89			nonInteraction: true
90		}
91		if (data.eventCategory && data.eventAction && data.eventLabel)
92			gtm.sendEvents({tClient: data});
93	}
94
95	function handleShowMoreToggle(payload){
96		var event = payload.eventContext,
97			widget = payload.widgetContext;
98		var data = {
99			eventCategory: widget.name,
100			eventAction: event.name,
101			eventLabel: event.displayText+" | "+event.refTitle,
102			nonInteraction: false
103		}
104		if (data.eventCategory && data.eventAction && data.eventLabel)
105			gtm.sendEvents({tClient: data});
106
107		if(widget.name === "Coupons"){
108			widget.name = "offers";
109		}
110		let ga4Data = {
111			eventName: "filter",
112			filterType: `${event.refTitle.substring(0,1).toUpperCase() + event.refTitle.substring(1)} | ${event.displayText}`,
113			itemType: event.itemType || widget.name.toLowerCase()
114		}
115		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
116			gtm.sendEvents({ tClient_ga4: ga4Data });
117	}
118
119	function handlePageChange(payload){
120		var event = payload.eventContext,
121			widget = payload.widgetContext;
122		var data = {
123			eventCategory: widget.name,
124			eventAction: event.name,
125			eventLabel: event.refTitle+" | "+event.displayText,
126			nonInteraction: false
127		}
128		if (data.eventCategory && data.eventAction && data.eventLabel)
129			gtm.sendEvents({tClient: data});
130
131		if(widget.name === "Coupons"){
132			widget.name = "offers";
133		}
134		let ga4Data = {
135			eventName: "filter",
136			filterType: `${event.refTitle} | ${event.displayText}`,
137			itemType: event.itemType || widget.name.toLowerCase()
138		}
139		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
140			gtm.sendEvents({ tClient_ga4: ga4Data });
141	}
142
143	function handleItemClick(payload){
144		var event = payload.eventContext,
145			widget = payload.widgetContext;
146		var data = {
147			eventCategory: widget.name,
148			eventAction: event.linkTo,
149			eventLabel: event.refTitle,
150			ot: event.type,
151			ltxt: event.displayText,
152			nonInteraction: false
153		}
154		/* alter action for once there */
155		if (event.recId !== undefined && event.recId.toString().indexOf("ot") > -1) {
156			data.eventAction = "OnceThere";
157		}
158		if (data.eventCategory && data.eventAction && data.eventLabel)
159			gtm.sendEvents({tClient: data});
160
161		if(widget.name === "Coupons"){
162			widget.name = "offers";
163		}
164		let crmCatSubcat = event?.crmc;
165		if (event?.v_crmc) {
166			crmCatSubcat = event.v_crmc;
167		} else if (crmCatSubcat && event.crmsc) {
168			crmCatSubcat += " | " + event.crmsc;
169		}	
170		var ga4Data = {
171			eventName: event.eventName,
172			itemType: event.itemType || widget.name.toLowerCase(),
173			itemName: event.itemName ?? event.refTitle,
174			linkObject: event.linkObject,
175			crmCatSubcat: crmCatSubcat
176		}
177		if (ga4Data.eventName && ga4Data.itemType && ga4Data.itemName && ga4Data.linkObject)
178			gtm.sendEvents({ tClient_ga4: ga4Data });
179	}
180
181	function handleMapPinClick(payload){
182		var event = payload.eventContext,
183			widget = payload.widgetContext;
184		var data = {
185			eventCategory: widget.name,
186			eventAction: event.name,
187			eventLabel: event.refTitle,
188			ot: event.type,
189			nonInteraction: false
190		}
191		if (data.eventCategory && data.eventAction && data.eventLabel)
192			gtm.sendEvents({tClient: data});
193	}
194 
195	function handleFilterChange (payload) {
196		var event = payload.eventContext,
197			widget = payload.widgetContext;
198		var data = {
199			eventCategory: widget.name,
200			eventAction: "Filter Change",
201			eventLabel: event.refTitle+" | "+event.displayText,
202			nonInteraction: false
203		}
204		if (data.eventCategory && data.eventAction && data.eventLabel)
205			gtm.sendEvents({tClient: data});
206
207		if(widget.name === "Coupons"){
208			widget.name = "offers";
209		}
210		let ga4Data = {
211			eventName: "filter",
212			filterType: `${event.refTitle.substring(0,1).toUpperCase() + event.refTitle.substring(1)} | ${event.displayText}`,
213			itemType: event.itemType || widget.name.toLowerCase()
214		}
215		if (ga4Data.eventName && ga4Data.filterType && ga4Data.itemType)
216			gtm.sendEvents({ tClient_ga4: ga4Data });
217	}
218	// end SEM tracking
219});
220
221// Lazy-load FontAwesome
222(function() {
223	var css = document.createElement('link');
224	css.href = 'https://use.fontawesome.com/releases/v5.14.0/css/all.css';
225	css.rel = 'stylesheet';
226	css.type = 'text/css';
227	document.getElementsByTagName('head')[0].appendChild(css);
228})();
229
230// Lazy-load js for widgets that have the [data-js] attribute on their root node
231(function() {
232	function initDataJs(searchScope, selector = '[data-js]' ){
233		require(['plugins_common_custom_lazyload'], function(lazyload) {
234			var widgetsToLoad = [];
235			let scope = searchScope ? searchScope : document;
236			var els = scope.querySelectorAll(selector);
237
238			for (var i = 0; i < els.length; i++) {
239				widgetsToLoad.push(els[i]);
240			}
241			
242			lazyload.lazy(widgetsToLoad, function(entry, io) {
243				var target = entry.target;
244				var jsFile = target.dataset.js;
245				var guid = target.dataset.guid;
246
247				require([jsFile], function(widget) {
248					widget.init(guid);
249					io.unobserve(target);
250				});
251			});
252		});
253	};
254
255	initDataJs();
256
257	let eventToSelectorMap = {
258		// each event needs a slightly different selector
259		"dynamicContentLoaded": "[data-dynamic-chosen] [data-js]",
260		"abContentLoaded": "[data-ab-chosen] [data-js]"
261	}
262	
263	Object.entries(eventToSelectorMap).forEach( event => {
264		const [eventName, selector] = event;
265		window.addEventListener(eventName, e => {
266			const collections = document.querySelector(`[data-guid="${e}"]`);
267			initDataJs(collections, selector);
268		});
269	});
270})();
271
272// Wrap core_textbox iframes to prevent horizontal overflow
273(function() {
274	const textBoxes = document.querySelectorAll('[data-sv-core-textbox]');
275	if (textBoxes.length) {
276		require(['plugins_common_custom_utils'], function(utils) {
277			textBoxes.forEach(utils.wrapIframes);
278		});
279	}
280})();
281
282// Init quickview textboxes
283(function() {
284	const textBoxes = document.querySelectorAll('[data-qv-enabled-textbox]');
285	if (textBoxes.length) {
286		require(['plugins_common_custom_quickview_textbox'], function (qv) {
287			qv.init();
288		});
289	}
290})();
291
292// Remove critical styles from head after all CSS files have loaded
293// This prevents a situation where the critical styles cause an override of the CSS in files
294const criticalStyles = document.querySelector('[data-critical-styles]');
295if (criticalStyles) {
296	window.addEventListener('load', e => criticalStyles.remove());
297}

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.