PageSourceSearch

https://nassaubay.com/Areas/Layout/Assets/Scripts/CarouselWidget.js

js nassaubay.com collected 2026-09-25 04:51:01 UTC 18,545 bytes, 546 lines download raw bytes

1; (function ($, window) {
2
3	var debug = false;
4	var diag = function (message) {
5		if (debug && window.console) {
6			console.log('[CarouselWidget] - ' + message);
7		}
8	};
9
10	var constants =
11	{
12		Fade: 'fade',
13		Slide: 'slide',
14		Automatic: 'automatically',
15		Manual: 'manual'
16	}
17
18	// Defaults
19	var defaults = {
20		transition: constants.Fade, //[fade or slide]
21		transitionTiming: 1,
22		groupAdvance: constants.Automatic, //[automatically or manual]
23		groupTiming: 5,
24		showArrows: true,
25		showPaging: true,
26		showDots: true,
27		sliderSelector: 'div.widgetCarousel-slider',
28		groupSelector: 'div.widgetCarousel-group',
29		itemsSelector: 'div.widgetCarousel-item',
30		forceHeight: false
31	};
32
33	var pageMarkup = '<li><a href="#slide" onclick="return false;" class="pagingItems" data-index="{0}">{0}</a></li>';
34	var separatorMarkup = '<li><span>...</span></li>';
35	var maxPageNumbers = 10;
36
37	//Constructor
38	window.CarouselWidget = function (options, element) {
39		var self = this;
40
41		//private vars/methods
42		self.element = element;
43		self.$carousel = $(self.element);
44		self.$prev = self.$carousel.find('.arrow.prev');
45		self.$next = self.$carousel.find('.arrow.next');
46		self.$pager = self.$carousel.find('.semanticList.pager');
47		self.$arrowSpans = self.$next.children('svg').add(self.$prev.children('svg'));
48		self.autoTransition = null;
49
50		self.initPaging = function () {
51			var appendPage = function (number) {
52				var $li = $(pageMarkup.replace(/\{0\}/g, number));
53				$li.children('a').unbind('click').click(function (e) {
54					e.preventDefault();
55					if (!$(this).parent().hasClass('disabled')) {
56						self.stopTransition();
57						self.show($(this).data('index'));
58					}
59				});
60				self.$pager.append($li);
61			};
62			var appendSeparator = function () {
63				var $li = $(separatorMarkup);
64				self.$pager.append($li);
65			};
66			var appendRange = function (start, end) {
67				for (var number = start; number <= end; number++) {
68					appendPage(number);
69				}
70			};
71
72			self.$pager.empty();
73			if (self.settings.showDots || self.$slides.length <= maxPageNumbers) {
74				for (var i = 0; i < self.$slides.length; i++) {
75					appendPage(i + 1);
76				}
77				diag('Paging initialized with ' + (self.settings.showDots ? 'dots' : 'numbers'));
78			} else {
79				if (self.currentSlide <= 3) {
80					appendRange(1, 4);
81					appendSeparator();
82					appendPage(self.$slides.length);
83				} else if (self.$slides.length - self.currentSlide < 3) {
84					appendPage(1);
85					appendSeparator();
86					appendRange(self.$slides.length - 3, self.$slides.length);
87				} else {
88					appendPage(1);
89					appendSeparator();
90					appendRange(self.currentSlide - 1, self.currentSlide + 1);
91					appendSeparator();
92					appendPage(self.$slides.length);
93				}
94				diag('Paging initialized with optimized numbers');
95			}
96			self.$pager.show();
97		};
98
99		self.updatePaging = function () {
100			if (self.$pager.is(':visible')) {
101				if (!self.settings.showDots && self.$slides.length > maxPageNumbers) {
102					self.initPaging();
103				}
104				self.$pager.find('.active').removeClass('active');
105				self.$pager.find('[data-index=' + self.currentSlide + '].pagingItems').parent().addClass('active');
106			}
107			self.updateArrowsHeight();
108		};
109
110		self.updateGraphicLinksWidgetClasses = function () {
111			var liveEditEnabled = getCookieValue("enableLiveEdit") === "true";
112			if (liveEditEnabled) {
113				return;
114			}
115
116			var isCarouselWide = self.$carousel.hasClass('wide');
117			var addClass = isCarouselWide ? 'wide' : 'narrow';
118			var removeClass = isCarouselWide ? 'narrow' : 'wide';
119
120			var $graphicLinksWidgets = self.$carousel.find('.widget.widgetGraphicLinks');
121
122			$graphicLinksWidgets.each(function () {
123				var $widget = $(this);
124
125				if ($widget.closest('.widgetCarousel')[0] !== self.$carousel[0]) {
126					return;
127				}
128
129				$widget.addClass(addClass).removeClass(removeClass);
130
131				$widget.find('.widgetGraphicLinksNav .row').addClass(addClass).removeClass(removeClass);
132			});
133		};
134
135		self.updateArrowsHeight = function () {
136			if (self.settings.showArrows) {
137				var slide = self.currentSlide > self.$slides.length
138					? 1
139					: (self.currentSlide < 1
140						? self.$slides.length
141						: self.currentSlide);
142				var top = $(self.$slides[slide - 1]).height() / 2;
143				if (top < 15) top = 15;
144				var centerCss = 'translateY(' + top + 'px)';
145				self.$arrowSpans.css({
146					'-webkit-transform': centerCss,
147					'-ms-transform': centerCss,
148					'-o-transform': centerCss,
149					'transform': centerCss
150				});
151			}
152		};
153
154		self.initArrows = function () {
155			self.$prev.unbind('click').click(function (e) {
156				e.preventDefault();
157				if (!$(this).hasClass('disabled')) {
158					self.$prev.addClass('disabled');
159					if (!self.$next.hasClass('disabled')) {
160						self.$next.addClass('disabled');
161						setTimeout(function() {
162							self.$next.removeClass('disabled');
163						}, self.settings.transitionTiming * 1000);
164					}
165					self.stopTransition();
166					self.movePrev();
167					if (document.activeElement !== document.body) document.activeElement.blur();
168					setTimeout(function() {
169						self.$prev.removeClass('disabled');
170					}, self.settings.transitionTiming * 1000);
171				}
172			});
173			self.$next.unbind('click').click(function (e) {
174				e.preventDefault();
175				if (!$(this).hasClass('disabled')) {
176					self.stopTransition();
177					self.moveNext();
178					if (document.activeElement !== document.body) document.activeElement.blur();
179				}
180			});
181			//Disabled arrows only if there is one slide. Otherwise, carousel is always circular
182			self.$prev.show()[(self.$slides.length <= 1) ? 'addClass' : 'removeClass']("disabled");
183			self.$next.show()[(self.$slides.length <= 1) ? 'addClass' : 'removeClass']("disabled");
184		};
185
186		self.startTransition = function () {
187			self.stopTransition();
188			var loopTransition = function (force) {
189				force = force || false;
190				if (force || self.autoTransition != null) {
191					self.autoTransition = window.setTimeout(function () {
192						self.moveNext(loopTransition);
193					}, self.settings.groupTiming * 1000);
194				}
195			};
196			loopTransition(true);
197		};
198
199		self.stopTransition = function () {
200			if (self.autoTransition != null) {
201				window.clearTimeout(self.autoTransition);
202				self.autoTransition = null;
203			}
204		};
205
206		self.setupTransition = function () {
207			var i,
208				m = self.$groups.length,
209				n = self.$items.length;
210			if (!self.slideByItems) {
211				//by groups => wide view
212				diag('Setup transition by groups. m=' + m + ', effect=' + self.settings.transition);
213				if (self.settings.transition === constants.Slide) {
214					self.$slider.css('left', '0');
215					self.$slider.css("margin-left", "100%").css("margin-right", "100%");
216
217					//adjust internally new groups
218					self.$groups = self.$carousel.find(self.settings.groupSelector);
219					m = self.$groups.length;
220
221					if (m > 1) {
222						self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease");
223					}
224
225				} else {
226					for (i = 0; i < m; i++) {
227						$(self.$groups[i]).css('left', (i * 100 * -1 / m) + '%').css('z-index', 1);
228					}
229				}
230				self.$slider.css('width', (m * 100) + '%');
231				self.$groups.css('width', (100 * 1 / m) + '%');
232			} else {
233				//by items => narrow view
234				diag('Setup transition by items. m=' + m + ', n=' + n + ', effect=' + self.settings.transition);
235				var $groupItems;
236				var j;
237				if (self.settings.transition === constants.Slide) {
238					self.$slider.css('left', '0');
239					self.$items.css('opacity', 1);
240					self.$slider.css("margin-left", "100%").css("margin-right", "100%");
241
242					//adjust internally new groups and items
243					self.$groups = self.$carousel.find(self.settings.groupSelector);
244					self.$items = self.$carousel.find(self.settings.itemsSelector);
245					m = self.$groups.length;
246					n = self.$items.length;
247					
248					if (n > 1) {
249						self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease");
250					}
251
252					for (i = 0; i < m; i++) {
253						$groupItems = $(self.$groups[i]).find(self.settings.itemsSelector);
254						$(self.$groups[i])
255							.css('width', (100 * $groupItems.length / n) + '%');
256						for (j = 0; j < $groupItems.length; j++) {
257							$($groupItems[j]).css('width', (1 / $groupItems.length) * 100 + '%');
258						}
259					}
260				} else {
261					for (i = 0; i < m; i++) {
262						var itemsLeft = 0;
263						$groupItems = $(self.$groups[i]).find(self.settings.itemsSelector);
264						if (i > 0) {
265							for (j = 0; j < i; j++) {
266								itemsLeft += $(self.$groups[j]).find(self.settings.itemsSelector).length;
267							}
268						}
269						$(self.$groups[i])
270							.css('width', (100 * $groupItems.length / n) + '%')
271							.css('left', (-100 * itemsLeft / n) + '%').css('z-index', 1);
272						for (j = 0; j < $groupItems.length; j++) {
273							$($groupItems[j]).css('width', (1 / $groupItems.length) * 100 + '%')
274								.css('left', -j / $groupItems.length * 100 + '%');
275						}
276					}
277				}
278
279				self.$slider.css('width', (n * 100) + '%');
280			}
281		};
282
283		self.init(options);
284
285		//Adding global onresize handlers
286		var onResize = function () {
287			self.onResize();
288		};
289
290		window.Pages.onResizeHandlers = window.Pages.onResizeHandlers || [];
291		window.Pages.onResizeHandlers.push(onResize);
292	};
293
294	//public methods
295	window.CarouselWidget.prototype = {
296		init: function (options) {
297			var self = this;
298
299			self.settings = $.extend({}, defaults, options);
300			self.$slider = self.$carousel.find(self.settings.sliderSelector);
301			self.$groups = self.$carousel.find(self.settings.groupSelector);
302			self.$items = self.$carousel.find(self.settings.itemsSelector);
303			self.slideByItems = self.settings.itemsSelector != null && self.settings.itemsSelector.length > 0;
304			self.$slides = self.slideByItems ? self.$items : self.$groups;
305			self.currentSlide = 1;
306
307			diag('Initing carouselId: ' + self.$carousel.attr('id'));
308			diag('# of slides: ' + self.$slides.length);
309
310			//Display and init arrows/paging if needed
311			self.$pager.hide();
312			self.$prev.hide();
313			self.$next.hide();
314			self.settings.showPaging && self.initPaging();
315			self.settings.showArrows && self.initArrows();
316
317			// Find play and pause buttons and attach event handlers
318			self.$pause = self.$carousel.find('.pause-btn');
319			self.$play = self.$carousel.find('.play-btn');
320
321			// Initially display pause button and hide play button
322			if (self.$play.length>0)
323				self.$play.hide();
324
325			if (self.$pause.length > 0) {
326				self.$pause.click(function () {
327					self.stopTransition();
328					$(this).hide();
329					self.$play.show();
330				});
331			}
332
333			if (self.$play.length > 0) {
334				self.$play.click(function () {
335					self.startTransition();
336					$(this).hide();
337					self.$pause.show();
338				});
339			}
340
341			self.setupTransition();
342
343			//Adjust height and show only first slide.
344			self.adjustHeight();
345			self.show(1);
346			self.updateGraphicLinksWidgetClasses();
347
348			// Set the z-index so group 1 is front
349			if (self.slideByItems && self.settings.transition === constants.Fade) {
350				$(self.$slides[0]).parent().css('z-index', 2);
351				$(self.$slides[0]).parent().siblings().css('z-index', 1);
352			}
353			
354			if (self.settings.groupAdvance === constants.Automatic && self.$slides.length > 1)
355				self.startTransition();
356		},
357		show: function (slide, callback) {
358			var self = this;
359			if (slide >= 1 && slide <= self.$slides.length) {
360				diag('Moving to slide #: ' + slide);
361				var originalSlide = self.currentSlide;
362				self.currentSlide = slide;
363					//Hide previous and display new one using transitions
364					switch (self.settings.transition) {
365						case constants.Fade:
366							if (originalSlide === self.currentSlide) {
367								//Hide all and display slide no effect.
368								self.$slides.css('opacity', 0).css('z-index', 1);
369								$(self.$slides[self.currentSlide - 1]).css('opacity', 1).css('z-index', 2);
370							} else {
371								// If slide by items, use to change the z-index of groups
372								if (self.slideByItems) {
373									$(self.$slides[self.currentSlide - 1]).parent().css('z-index',2);
374									$(self.$slides[self.currentSlide - 1]).parent().siblings().css('z-index', 1);
375								}
376								//Fade effect
377								$(self.$slides[originalSlide - 1]).animate({ opacity: 0 }, self.settings.transitionTiming * 1000, function () {
378									$(this).css('z-index', 1);
379								});
380								$(self.$slides[self.currentSlide - 1]).animate({ opacity: 1 }, self.settings.transitionTiming * 1000, function () {
381									$(this).css('z-index', 2);
382									if (typeof callback === 'function') {
383										callback();
384									}
385								});
386							}
387							break;
388						case constants.Slide:
389							if (originalSlide === self.currentSlide) {
390								//display slide no effect.
391								$(self.$slider.css('left', ((self.currentSlide) * -100) + '%'));
392							} else {
393								//slide effect
394								self.$slider.css("left", ((self.currentSlide) * -100) + '%');
395								setTimeout(function() {
396									if (typeof callback === 'function') {
397										callback();
398									}
399								}, self.settings.transitionTiming * 1000);
400							}
401							break;
402				}
403				//https://civicplus.tpondemand.com/entity/55058-pages-carousel-widget-does-not-show
404				window.setTimeout(function () {
405					self.updatePaging();
406				}, 500);
407			} else {
408				diag('Cannot move to slide #: ' + slide);
409			}
410		},
411		moveNext: function (callback) {
412			var self = this;
413			if (!self.$next.hasClass('disabled')) {
414				self.$next.addClass('disabled');
415				setTimeout(function() {
416					self.$next.removeClass('disabled');
417				}, self.settings.transitionTiming * 1000 + 50);
418			}
419			if (!self.$prev.hasClass('disabled')) {
420				self.$prev.addClass('disabled');
421				setTimeout(function() {
422					self.$prev.removeClass('disabled');
423				}, self.settings.transitionTiming * 1000 + 50);
424			}
425			var next = self.currentSlide === self.$slides.length ? 1 : self.currentSlide + 1;
426			if (next === 1 && self.settings.transition === constants.Slide) {
427				//Slide from Last to First
428				self.currentSlide = next;
429				var leftOffset = ((self.$slides.length + 1) * -100); //Last to phantom Last and then to actual First slide
430				self.$slider.css("left", leftOffset + '%');
431				self.$slides.first().css("transform","translateX(" + self.$slides.length * 100 + "%)");
432				setTimeout(function() {
433					self.$slider.css("transition", "none");
434					self.$slider.css('left', ((self.currentSlide) * -100) + '%');
435					setTimeout(function() { self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease"); }, 50);
436					self.$slides.first().css("transform","none");
437					if (typeof callback === 'function') {
438						callback();
439					}
440				}, self.settings.transitionTiming * 1000);
441				self.updatePaging();
442			} else
443				self.show(next, callback);
444		},
445		movePrev: function () {
446			var self = this;
447			if (!self.$next.hasClass('disabled')) {
448				self.$next.addClass('disabled');
449				setTimeout(function() {
450					self.$next.removeClass('disabled');
451				}, self.settings.transitionTiming * 1000 + 50);
452			}
453			if (!self.$prev.hasClass('disabled')) {
454				self.$prev.addClass('disabled');
455				setTimeout(function() {
456					self.$prev.removeClass('disabled');
457				}, self.settings.transitionTiming * 1000 + 50);
458			}
459			var prev = self.currentSlide === 1 ? self.$slides.length : self.currentSlide - 1;
460			if (prev === self.$slides.length && self.settings.transition === constants.Slide) {
461				//Slide from First to Last
462				self.currentSlide = prev;
463				var leftOffset = 0; //First to phantom First and then to actual Last slide
464				self.$slider.css("left", leftOffset + '%');
465				self.$slides.last().css("transform","translateX(-" + self.$slides.length * 100 + "%)");
466				setTimeout(function() {
467					self.$slider.css("transition", "none");
468					self.$slider.css('left', ((self.currentSlide) * -100) + '%');
469					setTimeout(function() { self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease"); }, 50);
470					self.$slides.last().css("transform","none");
471					if (typeof callback === 'function') {
472						callback();
473					}
474				}, self.settings.transitionTiming * 1000);
475				self.updatePaging();
476			} else
477				self.show(prev);
478		},
479
480		onResize: function () {
481			var self = this;
482			self.adjustHeight();
483			self.updateGraphicLinksWidgetClasses();
484		},
485		adjustHeight: function () {
486			var self = this;
487			if (self.settings.forceHeight) {
488				var maxHeight = 0;
489				for (var i = 0; i < self.$slides.length; i++) {
490					var slideHeight = $(self.$slides[i]).outerHeight(true);
491					if (slideHeight > maxHeight)
492						maxHeight = slideHeight;
493				}
494				if (self.settings.showPaging)
495					maxHeight += self.$pager.outerHeight(true);
496				self.$carousel.css('height', maxHeight + 'px');
497				diag('height adjusted to ' + maxHeight + 'px');
498			}
499		},
500		destroy: function () {
501			var self = this;
502			self.$pager.empty().hide();
503			self.$prev.unbind('click').hide();
504			self.$next.unbind('click').hide();
505			self.stopTransition();
506			self.$carousel.css('height', '');
507			self.$slider.css('width', '').css('left', '');
508			self.$groups.css('width', '').css('left', '').css('z-index', '').css('opacity', '');
509			self.$items.css('width', '').css('left', '').css('z-index', '').css('opacity', '');
510		}
511	}
512
513	/* jQuery Plugin Support */
514	$.fn.carouselWidget = function (options) {
515		if (typeof options === 'string') {
516			var args = Array.prototype.slice.call(arguments, 1);
517			this.each(function () {
518				var instance = $.data(this, 'carouselWidget');
519				if (!instance) {
520					diag("cannot call methods on carouselWidget prior to initialization; " +
521					"attempted to call method '" + options + "'");
522					return;
523				}
524				if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
525					diag("no such method '" + options + "' for carouselWidget instance");
526					return;
527				}
528				instance[options].apply(instance, args);
529			});
530		}
531		else {
532			this.each(function () {
533				var instance = $.data(this, 'carouselWidget');
534				if (instance) {
535					instance.init(options);
536				}
537				else {
538					$.data(this, 'carouselWidget', new window.CarouselWidget(options, this));
539				}
540			});
541		}
542
543		return this;
544	};
545
546})(jQuery, window);

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.