1document.addEventListener('DOMContentLoaded', function() { 2 function getInitialTargetIndex(slides) { 3 const highlightIndex = slides.findIndex(slide => slide.getAttribute('data-highlight') === 'true'); 4 if (highlightIndex !== -1) return highlightIndex; 5 6 const todayStr = new Date().toISOString().split('T')[0]; 7 const todayIndex = slides.findIndex(slide => { 8 const eventDate = slide.getAttribute('data-event-date'); 9 return eventDate && eventDate.startsWith(todayStr); 10 }); 11 12 return todayIndex !== -1 ? todayIndex : 0; 13 } 14 15 function updateActiveDayClass(index, slides, container) { 16 const currentSlide = slides[index]; 17 if (!currentSlide) return; 18 19 const eventDateTime = currentSlide.getAttribute('data-event-date'); 20 const category = currentSlide.getAttribute('data-category'); 21 const scope = container.closest('.tab-pane'); 22 if (!scope) return; 23 24 if (eventDateTime) { 25 const eventDate = eventDateTime.split(' ')[0]; 26 27 if (window.innerWidth > 825) { 28 scope.querySelectorAll('[data-day-date].active-slide').forEach(el => el.classList.remove('active-slide')); 29 const dayEl = scope.querySelector(`[data-day-date="${eventDate}"]`); 30 if (dayEl) dayEl.classList.add('active-slide'); 31 } else { 32 scope.querySelectorAll('[data-day-datemobile].active-slide-mobile').forEach(el => el.classList.remove('active-slide-mobile')); 33 const dayEl = scope.querySelector(`[data-day-datemobile="${eventDate}"]`); 34 if (dayEl) dayEl.classList.add('active-slide-mobile'); 35 } 36 } 37 38 const sidebar = scope.querySelector('.calendar-sidebar .swiper-container'); 39 if (sidebar && category) { 40 sidebar.setAttribute('data-category', category); 41 } 42 43 // Loop over all h3 elements inside this scope 44 const headings = scope.querySelectorAll('h3.tribe-common-h4');
45 headings.forEach(h3 => { 46 h3.setAttribute('data-category', category); 47 48 // Find the closest wrapper div (customize this selector as needed) 49 const wrapper = h3.closest('.tribe-events-calendar-month__day'); 50 if (wrapper) { 51 wrapper.classList.add('tribe-events-calendar-month__day'); 52 wrapper.setAttribute('data-category', category); 53 } 54 }); 55 if ($(window).width() < 825) { 56 57 58 const categoriesToRemove = ['dors-west', 'dors-central', 'dors-northwest']; 59 60 $('.school-events.school-buletin .dors-south-div .tribe-events-calendar-month__day-cell').each(function() { 61 const $el = $(this); 62 const categoryAttr = $el.attr('data-category'); 63 64 // Proceed only if data-category exists and is not empty 65 if (typeof categoryAttr !== 'undefined' && categoryAttr.length > 0) { 66 let categories = categoryAttr.split(','); 67 68 // Filter out all categories that are in the removal list 69 categories = categories.filter(cat => !categoriesToRemove.includes(cat.trim())); 70 71 // Update the attribute (can be empty if all were removed) 72 $el.attr('data-category', categories.join(',')); 73 } 74 }); 75 76 const categoriesToRemove2 = ['dors-south', 'dors-central', 'dors-northwest']; 77 78 $('.school-events.school-buletin .dors-west-div .tribe-events-calendar-month__day-cell').each(function() { 79 const $el = $(this); 80 const categoryAttr = $el.attr('data-category'); 81 82 // Proceed only if data-category exists and is not empty 83 if (typeof categoryAttr !== 'undefined' && categoryAttr.length > 0) { 84 let categories = categoryAttr.split(','); 85 86 // Filter out all categories that are in the removal list 87 categories = categories.filter(cat => !categoriesToRemove2.includes(cat.trim())); 88 89 // Update the attribute (can be empty if all were removed) 90 $el.attr('data-category', categories.join(',')); 91 } 92 }); 93 94 const categoriesToRemove3 = ['dors-south', 'dors-west', 'dors-northwest']; 95 96 $('.school-events.school-buletin .dors-central-div .tribe-events-calendar-month__day-cell').each(function() { 97 const $el = $(this); 98 const categoryAttr = $el.attr('data-category'); 99 100 // Proceed only if data-category exists and is not empty 101 if (typeof categoryAttr !== 'undefined' && categoryAttr.length > 0) { 102 let categories = categoryAttr.split(','); 103 104 // Filter out all categories that are in the removal list 105 categories = categories.filter(cat => !categoriesToRemove3.includes(cat.trim())); 106 107 // Update the attribute (can be empty if all were removed) 108 $el.attr('data-category', categories.join(',')); 109 } 110 }); 111 112 const categoriesToRemove4 = ['dors-south', 'dors-west', 'dors-central']; 113 114 $('.school-events.school-buletin .dors-northwest-div .tribe-events-calendar-month__day-cell').each(function() { 115 const $el = $(this); 116 const categoryAttr = $el.attr('data-category'); 117 118 // Proceed only if data-category exists and is not empty 119 if (typeof categoryAttr !== 'undefined' && categoryAttr.length > 0) { 120 let categories = categoryAttr.split(','); 121 122 // Filter out all categories that are in the removal list 123 categories = categories.filter(cat => !categoriesToRemove4.includes(cat.trim())); 124 125 // Update the attribute (can be empty if all were removed) 126 $el.attr('data-category', categories.join(',')); 127 } 128 }); 129 130 const sidebar = scope.querySelector('.calendar-sidebar .swiper-container'); 131 if (sidebar) { 132 sidebar.setAttribute('data-category', category || ''); 133 } 134 135 const headings = scope.querySelectorAll('.tab-pane .tribe-events-calendar-month__day-cell'); 136
137 headings.forEach(h3 => { 138 // Always set the attribute â with category if available, else blank 139 h3.setAttribute('data-mobile-category', category || ''); 140 141 const wrapper = h3.closest('.tab-pane .tribe-events-calendar-month__day'); 142 if (wrapper) { 143 wrapper.classList.add('tribe-events-calendar-month__day'); 144 wrapper.setAttribute('data-mobile-category', category || ''); 145 } 146 }); 147 148 149 } 150 151 } 152 153 function toggleNavigationVisibility(container, slides, activeIndex) { 154 const currentSlide = slides[activeIndex]; 155 const nextBtn = container.querySelector('.swiper-button-next'); 156 const prevBtn = container.querySelector('.swiper-button-prev'); 157 const navWrapper = container.closest('.tab-pane')?.querySelector('.s-nbavigaton'); 158 159 if (!currentSlide || !nextBtn || !prevBtn) return; 160 161 const eventDateTime = currentSlide.getAttribute('data-event-date'); 162 if (!eventDateTime) { 163 nextBtn.style.display = 'none'; 164 prevBtn.style.display = 'none'; 165 if (navWrapper) navWrapper.style.display = 'none'; 166 return; 167 } 168 169 const eventDate = eventDateTime.split(' ')[0]; 170 const sameDateSlides = slides 171 .map((slide, i) => ({ 172 slide, 173 index: i 174 })) 175 .filter(item => { 176 const date = item.slide.getAttribute('data-event-date'); 177 return date && date.startsWith(eventDate); 178 }); 179 180 const showNavigation = sameDateSlides.length > 1; 181 const currentInGroupIndex = sameDateSlides.findIndex(item => item.index === activeIndex); 182 183 nextBtn.style.display = showNavigation ? '' : 'none'; 184 prevBtn.style.display = showNavigation ? '' : 'none'; 185 if (navWrapper) { 186 navWrapper.style.display = showNavigation ? '' : 'none'; 187 188 const scope = container.closest('.tab-pane'); 189 if (scope) { 190 const btnGrey = scope.querySelector('.school-events .btn-grey'); 191 if (btnGrey) { 192 if (showNavigation) { 193 btnGrey.classList.add('active-nav-visible'); // You can use any class name you need 194 } else { 195 btnGrey.classList.remove('active-nav-visible'); 196 } 197 } 198 } 199 } 200 201 if (showNavigation) { 202 nextBtn.classList.toggle('swiper-button-disabled', currentInGroupIndex === sameDateSlides.length - 1); 203 prevBtn.classList.toggle('swiper-button-disabled', currentInGroupIndex === 0); 204 } 205 } 206 207 function initSwiper(container) { 208 if (!container) return; 209 if (container.swiper && !container.swiper.destroyed) { 210 container.swiper.update(); 211 return; 212 } 213 214 const swiperWrapper = container.querySelector('.swiper-wrapper'); 215 const slides = Array.from(container.querySelectorAll('.swiper-slide')); 216 swiperWrapper.innerHTML = '';
217 slides.forEach(slide => swiperWrapper.appendChild(slide)); 218 219 const targetIndex = getInitialTargetIndex(slides); 220 221 const swiper = new Swiper(container, { 222 loop: false, 223 initialSlide: targetIndex, 224 slidesPerView: 1, 225 spaceBetween: 20, 226 navigation: { 227 nextEl: container.querySelector('.swiper-button-next'), 228 prevEl: container.querySelector('.swiper-button-prev'), 229 }, 230 pagination: { 231 el: container.querySelector('.swiper-pagination'), 232 clickable: true, 233 }, 234 observer: true, 235 observeParents: true, 236 simulateTouch: window.innerWidth <= 767, // â Allow swipe only on mobile 237 allowTouchMove: window.innerWidth <= 767 // â Disable drag on desktop 238 }); 239 240 241 updateActiveDayClass(targetIndex, slides, container); 242 toggleNavigationVisibility(container, slides, targetIndex); 243 244 swiper.on('slideChange', function() { 245 updateActiveDayClass(swiper.activeIndex, slides, container); 246 toggleNavigationVisibility(container, slides, swiper.activeIndex); 247 248 const scope = container.closest('.tab-pane'); 249 if (scope) { 250 scope.querySelectorAll('[data-day-date].activeclick, [data-day-datemobile].activeclick') 251 .forEach(el => el.classList.remove('activeclick')); 252 } 253 }); 254 255 // test3 SAFELY attach custom prev/next button logic to avoid stacking 256 const nextBtn = container.querySelector('.swiper-button-next'); 257 const prevBtn = container.querySelector('.swiper-button-prev'); 258 259 if (nextBtn && prevBtn) { 260 nextBtn.onclick = function(e) { 261 e.preventDefault(); 262 263 const currentIndex = swiper.activeIndex; 264 const currentSlide = swiper.slides[currentIndex]; 265 const currentDate = currentSlide?.getAttribute('data-event-date')?.split(' ')[0]; 266 267 let sameDateSlides = []; 268 269 try { 270 if (typeof swiper.slides.map === 'function') { 271 sameDateSlides = swiper.slides 272 .map((slide, index) => ({ 273 slide, 274 index 275 })) 276 .filter(item => { 277 const date = item.slide.getAttribute('data-event-date'); 278 return date && date.split(' ')[0] === currentDate; 279 }); 280 } else { 281 return; // silent exit if map is not a function 282 } 283 } catch (err) { 284 return; // completely silent fail 285 } 286 287 const currentPos = sameDateSlides.findIndex(item => item.index === currentIndex); 288 const nextItem = sameDateSlides[currentPos + 1]; 289 290 if (nextItem) { 291 swiper.slideTo(nextItem.index); 292 } 293 }; 294 295 296 297 298 prevBtn.onclick = function(e) { 299 e.preventDefault(); 300 301 const currentIndex = swiper.activeIndex; 302 const currentSlide = swiper.slides[currentIndex]; 303 const currentDate = currentSlide?.getAttribute('data-event-date')?.split(' ')[0]; 304 305 let sameDateSlides = []; 306 307 try { 308 if (typeof swiper.slides.map === 'function') { 309 sameDateSlides = swiper.slides 310 .map((slide, index) => ({ 311 slide, 312 index 313 })) 314 .filter(item => { 315 const date = item.slide.getAttribute('data-event-date'); 316 return date && date.split(' ')[0] === currentDate; 317 }); 318 } else { 319 return; 320 } 321 } catch (err) { 322 return; 323 } 324 325 const currentPos = sameDateSlides.findIndex(item => item.index === currentIndex); 326 const prevItem = sameDateSlides[currentPos - 1]; 327 328 if (prevItem) { 329 swiper.slideTo(prevItem.index); 330 } 331 }; 332 333 334 335 336 } 337 338 container.swiper = swiper; 339 } 340 341 const activeTabPane = document.querySelector('.tab-pane:not(.hidden-bul)'); 342 if (activeTabPane) { 343 const container = activeTabPane.querySelector('.swiper-container'); 344 if (container) { 345 initSwiper(container); 346 } 347 } 348 349 document.addEventListener('click', function(e) { 350 const targetDesktop = e.target.closest('[data-day-date]'); 351 const targetMobile = e.target.closest('[data-day-datemobile]'); 352 const clickedDate = targetDesktop?.getAttribute('data-day-date') || targetMobile?.getAttribute('data-day-datemobile'); 353 if (!clickedDate) return; 354 355 const scope = targetDesktop?.closest('.tab-pane') || targetMobile?.closest('.tab-pane'); 356 if (!scope) return; 357 358 scope.querySelectorAll('[data-day-date].activeclick, [data-day-datemobile].activeclick') 359 .forEach(el => el.classList.remove('activeclick')); 360 361 if (targetDesktop) targetDesktop.classList.add('activeclick'); 362 if (targetMobile) targetMobile.classList.add('activeclick'); 363 364 const container = scope.querySelector('.swiper-container'); 365 if (!container || !container.swiper) return; 366 367 const slides = Array.from(container.querySelectorAll('.swiper-slide')); 368 const matchIndex = slides.findIndex(slide => { 369 const slideDate = slide.getAttribute('data-event-date'); 370 return slideDate && slideDate.startsWith(clickedDate); 371 }); 372 373 if (matchIndex !== -1) { 374 container.swiper.slideTo(matchIndex); 375 } 376 }); 377 378 $(document).ready(function() { 379 $('.school-buletin-tabs .tab-link').click(function() { 380 $('.school-buletin-tabs .tab-link').removeClass('active-bul'); 381 $(this).addClass('active-bul'); 382 383 $('.school-wappers .tab-pane').addClass('hidden-bul'); 384 const target = $(this).data('target'); 385 const $targetPane = $(target); 386 if ($targetPane.length === 0) return; 387 388 $targetPane.removeClass('hidden-bul'); 389 390 setTimeout(() => { 391 const container = $targetPane.find('.swiper-container').get(0); 392 if (container) { 393 initSwiper(container); 394 } 395 396 window.dispatchEvent(new Event('resize')); 397 $('.tribe-events-calendar-month:visible').each(function() { 398 const calendar = $(this).data('fc'); 399 if (calendar && typeof calendar.updateSize === 'function') { 400 calendar.updateSize(); 401 } 402 }); 403 404 if (typeof tribe !== 'undefined' && tribe.events?.views?.manager?.refresh) { 405 tribe.events.views.manager.refresh(); 406 } 407 }, 50); 408 }); 409 }); 410}); 411 412
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.