PageSourceSearch

https://iguidebythebay.ca/wp-content/plugins/tlp-team/assets/js/iso-filter.js?ver=1790258990

js iguidebythebay.ca collected 2026-09-24 14:11:13 UTC 4,586 bytes, 119 lines download raw bytes

1
2/* =========================================================================
3 * Isotope filter bar — count badges + sliding glider (redesign, appended).
4 * Self-contained: enhances the plugin's .ttp-isotope-buttons on EVERY isotope
5 * layout (global nav style), not just isotope-free. Counts are read from the
6 * loaded .isotope-item items in the .rt-content-loader row; the glider is a
7 * span that slides to the active pill. Adds .rttm-iso-has-glider to the group so
8 * the CSS can make the active button transparent (glider provides the gradient);
9 * without JS the CSS keeps a gradient background on .selected as a fallback.
10 * ========================================================================= */
11(function ($) {
12	'use strict';
13
14	function positionGlider($group) {
15		var $active = $group.children('button.selected').filter(':visible').first();
16		var $glider = $group.children('.rttm-iso-glider');
17		if (!$active.length || !$glider.length) {
18			$glider.css('opacity', 0);
19			return;
20		}
21		var btn = $active[0];
22		$glider.css({
23			left: btn.offsetLeft + 'px',
24			top: btn.offsetTop + 'px',
25			width: btn.offsetWidth + 'px',
26			height: btn.offsetHeight + 'px',
27			opacity: 1
28		});
29	}
30
31	function initGroup($group) {
32		if ($group.data('rttmIsoInit')) {
33			positionGlider($group);
34			return;
35		}
36		$group.data('rttmIsoInit', true);
37
38		// `.rt-content-loader` is the row shared by EVERY isotope layout (it wraps both the
39		// filter bar and the items), and `.isotope-item` is the item class every isotope layout
40		// uses — so counting works on any isotope layout, not just isotope-free.
41		var $row = $group.closest('.rt-content-loader');
42
43		// 1. count badge per button (from the loaded items); hide empty non-"all" filters
44		$group.children('button').each(function () {
45			var $btn = $(this);
46			var f = $btn.attr('data-filter');
47			var count;
48			try {
49				count = (f === '*') ? $row.find('.isotope-item').length : $row.find('.isotope-item' + f).length;
50			} catch (e) {
51				count = 0;
52			}
53			if (count === 0 && f !== '*') {
54				$btn.hide();
55				return;
56			}
57			if (!$btn.children('.count').length) {
58				$btn.append(' <span class="count">' + count + '</span>');
59			}
60		});
61
62		// 2. glider element (behind the pills) + flag the group so CSS clears the button bg
63		if (!$group.children('.rttm-iso-glider').length) {
64			$group.prepend('<span class="rttm-iso-glider" aria-hidden="true"></span>');
65		}
66		$group.addClass('rttm-iso-has-glider');
67
68		// 3. slide the glider when a pill is clicked (after the plugin toggles .selected)
69		$group.on('click.rttmIso', 'button', function () {
70			setTimeout(function () { positionGlider($group); }, 0);
71		});
72
73		positionGlider($group);
74		// re-measure once more after fonts/layout settle
75		setTimeout(function () { positionGlider($group); }, 250);
76	}
77
78	function initAll() {
79		$('.rt-team-container .ttp-isotope-buttons').each(function () {
80			initGroup($(this));
81		});
82	}
83
84	$(window).on('load', initAll);
85	$(document).ready(initAll);
86
87	// Expose the initialiser for contexts that inject the filter-bar markup AFTER page load,
88	// where the load/ready handlers above never fire — e.g. the admin shortcode preview, which
89	// re-renders via AJAX on every form change. Safe to call repeatedly: initGroup is idempotent
90	// per group (guards on .data('rttmIsoInit')), and the preview replaces the DOM each render so
91	// a fresh group re-initialises cleanly.
92	window.rttmIsoFilter = { init: initAll, initGroup: initGroup, position: positionGlider };
93
94	// Elementor renders widgets asynchronously and, in the EDITOR, re-renders them on every
95	// change WITHOUT a page reload — so the load/ready handlers above never fire for the fresh
96	// DOM. Hook the widget's ready event so the counts + glider initialise each time it renders
97	// (idempotent: initGroup guards with .data('rttmIsoInit'), and the editor recreates the DOM
98	// so the guard is naturally clear on the new node). Runs on the real frontend too, harmless.
99	$(window).on('elementor/frontend/init', function () {
100		if (!window.elementorFrontend || !elementorFrontend.hooks || !elementorFrontend.hooks.addAction) {
101			return;
102		}
103		elementorFrontend.hooks.addAction('frontend/element_ready/rttm-team-isotope.default', function ($scope) {
104			$scope.find('.ttp-isotope-buttons').each(function () {
105				initGroup($(this));
106			});
107		});
108	});
109
110	var resizeT;
111	$(window).on('resize', function () {
112		clearTimeout(resizeT);
113		resizeT = setTimeout(function () {
114			$('.rt-team-container .ttp-isotope-buttons').each(function () {
115				positionGlider($(this));
116			});
117		}, 150);
118	});
119})(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.