1(() => { 2 // Debounce 3 const debounce = (callback, wait) => { 4 let timeoutId = null; 5 6 return (...args) => { 7 window.clearTimeout(timeoutId); 8 9 timeoutId = window.setTimeout(() => { 10 callback.apply(null, args); 11 }, wait); 12 }; 13 }; 14 15 // Class function 16 const elementClass = { 17 add: (el, className) => { 18 let element = document.querySelector(el); 19 20 element.classList.add(className); 21 }, 22 23 remove: (el, className) => { 24 let element = document.querySelector(el); 25 26 element.classList.remove(className); 27 }, 28 29 toggle: (el, className) => { 30 let element = document.querySelector(el); 31 32 element.classList.toggle(className); 33 }, 34 }; 35 36 // Navbar toggle button 37 const navbarCollapse = document.querySelector("#navbarText"); 38 39 const navbarToggle = () => { 40 elementClass.toggle(".pvl-header", "is-collapsed"); 41 elementClass.toggle(".bi.bi-list", "text-white"); 42 }; 43 44 navbarCollapse.addEventListener("hide.bs.collapse", () => { 45 navbarToggle(); 46 }); 47 48 navbarCollapse.addEventListener("show.bs.collapse", () => { 49 navbarToggle(); 50 }); 51 52 // Latest news, Match schedule, Match recap slider 53 var swiper = new Swiper(".swiper.cards-slider", { 54 slidesPerView: "auto", 55 lazy: true, 56 spaceBetween: 25, 57 grabCursor: true, 58 breakpoints: { 59 576: { 60 slidesPerView: "auto", 61 }, 62 768: { 63 slidesPerView: 2, 64 }, 65 1200: { 66 slidesPerView: 3, 67 }, 68 }, 69 navigation: { 70 nextEl: ".swiper.cards-slider .swiper-button-next", 71 prevEl: ".swiper.cards-slider .swiper-button-prev", 72 }, 73 on: { 74 init: () => { 75 let swiperSlider = document.querySelectorAll(".swiper"); 76 77 if (swiperSlider) { 78 swiperSlider.forEach((item) => { 79 item.style.visibility = "visible"; 80 }); 81 } 82 }, 83 }, 84 }); 85 86 // Featured videos slider 87 var swiper = new Swiper(".swiper.featured-videos", { 88 slidesPerView: "auto", 89 lazy: true, 90 spaceBetween: 25, 91 grabCursor: true, 92 breakpoints: { 93 576: { 94 slidesPerView: "auto", 95 }, 96 768: { 97 slidesPerView: 2, 98 }, 99 }, 100 navigation: { 101 nextEl: ".swiper.featured-videos .swiper-button-next", 102 prevEl: ".swiper.featured-videos .swiper-button-prev", 103 }, 104 }); 105 106 // Player of the game slider 107 var swiper = new Swiper(".swiper.player-of-the-game", { 108 slidesPerView: 1, 109 effect: "fade", 110 fadeEffect: { 111 crossFade: true, 112 }, 113 navigation: { 114 nextEl: ".swiper.player-of-the-game .swiper-button-next", 115 prevEl: ".swiper.player-of-the-game .swiper-button-prev", 116 }, 117 }); 118 119 // Brackets scroll horizontal 120 var swiper = new Swiper(".swiper.brackets", { 121 slidesPerView: "auto", 122 freeMode: true, 123 grabCursor: true, 124 }); 125 126 // Player stats card slider 127 var swiper = new Swiper(".swiper.player-stats-cards", { 128 slidesPerView: "auto", 129 lazy: true, 130 spaceBetween: 30, 131 grabCursor: true, 132 navigation: { 133 nextEl: ".swiper.player-stats-cards .swiper-button-next", 134 prevEl: ".swiper.player-stats-cards .swiper-button-prev", 135 }, 136 }); 137 138 // All teams slider 139 var swiper = new Swiper(".swiper.all-teams", { 140 loop: true, 141 lazy: true, 142 spaceBetween: 5, 143 grabCursor: true, 144 centeredSlides: true, 145 autoplay: { 146 delay: 3000, 147 }, 148 breakpoints: { 149 576: { 150 slidesPerView: 1, 151 }, 152 768: { 153 slidesPerView: 3, 154 }, 155 992: { 156 slidesPerView: 4, 157 }, 158 1200: { 159 slidesPerView: 5, 160 }, 161 }, 162 //added 163 navigation: { 164 nextEl: ".swiper.all-teams .swiper-button-next", 165 prevEl: ".swiper.all-teams .swiper-button-prev", 166 }, 167 on: { 168 init: () => { 169 let swiperSlider = document.querySelectorAll(".swiper"); 170 171 if (swiperSlider) { 172 swiperSlider.forEach((item) => { 173 item.style.visibility = "visible"; 174 }); 175 } 176 }, 177 }, 178 //added 179 }); 180
181 // videosPage search filter if the videos are loaded all in the page 182 /*const videoFilter = { 183 match: () => { 184 let qsRegex; 185 186 let quicksearch = document.querySelector(".iso-filter-quicksearch"); 187 if (quicksearch) { 188 quicksearch.addEventListener( 189 "input", 190 debounce(() => { 191 qsRegex = new RegExp(quicksearch.value.trim(), "gi"); 192 193 let videoContainers = document.querySelectorAll(".videos-posts-container .col"); 194 let noResultsMessage = document.getElementById("noResultsMessage"); 195 let hasResults = false; 196 197 videoContainers.forEach((container) => { 198 let videoTitleElement = container.querySelector(".video-title"); 199 200 if (videoTitleElement) { 201 let videoTitle = videoTitleElement.textContent; 202 let isMatch = qsRegex ? videoTitle.match(qsRegex) : true; 203 204 container.style.display = isMatch ? "block" : "none"; 205 206 if (isMatch) { 207 hasResults = true; 208 } 209 } 210 }); 211 212 if (noResultsMessage) { 213 noResultsMessage.style.display = hasResults ? "none" : "block"; 214 } 215 216 }, 300) 217 ); 218 } 219 }, 220}; 221 222videoFilter.match();*/ 223 224 225 // Isotope filtering 226 const isotopeFilter = { 227 filterButton: () => { 228 return ".iso-filter-button"; 229 }, 230 label: () => { 231 document.body.addEventListener("click", function (event) { 232 if (event.target.matches(isotopeFilter.filterButton())) { 233 let label = event.target.getAttribute("data-label"), 234 filterLabel = document.querySelector(".iso-filter-label"); 235 236 if(filterLabel){ 237 filterLabel.textContent = label; 238 } 239 } else { 240 return; 241 } 242 }); 243 }, 244 arrange: () => { 245 document.body.addEventListener("click", function (event) { 246 if (event.target.matches(isotopeFilter.filterButton())) { 247 let filterValue = event.target.getAttribute("data-filter"); 248 249 if(iso){ 250 iso.arrange({ filter: filterValue }); 251 } 252 } else { 253 return; 254 } 255 }); 256 }, 257 match: () => { 258 // quick search regex 259 let qsRegex; 260 let filterSelector = "*"; 261 262 // use value of search field to filter 263 let quicksearch = document.querySelector(".iso-filter-quicksearch"); 264 if (quicksearch) { 265 quicksearch.addEventListener( 266 "keyup", 267 debounce(() => { 268 qsRegex = new RegExp(quicksearch.value, "gi"); 269 270 let filterLabel = document.querySelector(".iso-filter-label"); 271 272 if (quicksearch.value == "") { 273 filterLabel.textContent = quicksearch.getAttribute("data-default-label"); 274 } else { 275 filterLabel.textContent = `Search for "${quicksearch.value}"`; 276 } 277 iso.arrange({ 278 filter: (itemElem) => { 279 var search = qsRegex ? itemElem.textContent.match(qsRegex) : true; 280 var filterRes = filterSelector != "*" ? itemElem.dataset.cat.includes(filterSelector) : true; 281 282 return search && filterRes; 283 }, 284 }); 285 }, 100) 286 ); 287 } 288 }, 289 }; 290 291 292 // Teams page isotope filtering 293 const playerPool = document.querySelector(".player-pool-grid"); 294 295 if (playerPool) { 296 var iso = new Isotope(playerPool, { 297 itemSelector: ".player-grid-item", 298 layoutMode: "fitRows", 299 }); 300 } 301 302 const scheduleGrid = document.querySelector(".schedule-grid"); 303 304 if (scheduleGrid) { 305 var iso = new Isotope(scheduleGrid, { 306 itemSelector: ".schedule-grid-item", 307 layoutMode: "fitRows", 308 }); 309 } 310 311 312 // Teams logo slider 313 var swiper = new Swiper(".swiper.teams-logo", { 314 initialSlide: 6, 315 lazy: true, 316 grabCursor: true, 317 slidesPerView: 2, 318 spaceBetween: 5, /*Modified from 30 */ 319 centeredSlides: true, 320 slideToClickedSlide: true, 321 breakpoints: { 322 576: { 323 slidesPerView: 4, 324 }, 325 768: { 326 slidesPerView: 4, 327 }, 328 992: { 329 slidesPerView: 6, 330 }, 331 1200: { 332 slidesPerView: 13, /*Modified from 10 */ 333 }, 334 }, 335 on: { 336 init: isotopeFilter.match(), 337 init: () => { 338 let quicksearch = document.querySelector(".iso-filter-quicksearch"); 339 if (quicksearch) { 340 quicksearch.addEventListener("keyup", () => { 341 let teamsLogo = document.querySelectorAll(".teams-logo img"); 342 343 teamsLogo.forEach((item) => { 344 item.classList.remove("opacity-100"); 345 }); 346 }); 347 } 348 }, 349 init: () => { 350 let swiperSlider = document.querySelectorAll(".swiper"); 351 352 if (swiperSlider) { 353 swiperSlider.forEach((item) => { 354 item.style.visibility = "visible"; 355 }); 356 } 357 }, 358 click: isotopeFilter.arrange(), 359 click: isotopeFilter.label(), 360 click: (active = () => { 361 // Active button 362 document.body.addEventListener("click", function (event) { 363 if (event.target.matches(isotopeFilter.filterButton())) { 364 let teamsLogo = document.querySelectorAll(".teams-logo img"), 365 quicksearch = document.querySelector(".iso-filter-quicksearch"); 366 367 teamsLogo.forEach((logo) => { 368 logo.classList.remove("opacity-100"); 369 }); 370 371 event.target.classList.add("opacity-100"); 372 373 if (quicksearch) { 374 quicksearch.value = ""; 375 } 376 } else { 377 return; 378 } 379 }); 380 }), 381 }, 382 }); 383 384 385 // Infinite scroll news 386 const newsPosts = document.querySelector(".news-posts-container"); 387 388 if (newsPosts) {
389 let currentRecord = newsPosts.children.length; 390 391 let infScroll = new InfiniteScroll(newsPosts, { 392 path: function () { 393 return `https://pvl.ph/news/loadmore`; 394 }, 395 responseBody: "json", 396 status: ".page-load-status", 397 scrollThreshold: 0, 398 history: false, 399 fetchOptions: { 400 method: "POST", 401 headers: { 402 "Content-Type": "application/x-www-form-urlencoded", 403 }, 404 body: "group_no=51", 405 }, 406 }); 407 408 409 let proxyElem = document.createElement("div"); 410 411 infScroll.on("load", function (body) { 412 let records = body, 413 recordPaginate = currentRecord * infScroll.loadCount, 414 recordPaginateRange = recordPaginate + currentRecord, 415 recordSlice = records.slice(recordPaginate, recordPaginateRange); 416 417 if (recordSlice.length !== 0) { 418 let records = recordSlice; 419 420 var itemsHTML = records.map(getNewsPost).join(""); 421 422 proxyElem.innerHTML = itemsHTML; 423 424 newsPosts.append(...proxyElem.children); 425 } else { 426 infScroll.destroy(); 427 } 428 }); 429 430 function getNewsPost({ title, date_posted, image_local, slug }) { 431 return ` 432 <div class="col"> 433 <div class="card text-white overflow-hidden"> 434 <a href="/news/${slug}" class="text-white"> 435 <div class="ratio ratio-4x3"> 436 <img src="${image_local}" class="card-img object-fit-cover img-fluid" alt="${title}" width="493" height="207" /> 437 </div> 438 <div class="card-img-overlay bg-gradient row align-items-end"> 439 <div class="col"> 440 <h2 class="card-title fs-8 fw-bold mb-0">${title}</h2> 441 </div> 442 <div class="col-auto"> 443 <span class="card-text fs-5">${date_posted}</span> 444 </div> 445 </div> 446 </a> 447 </div> 448 </div> 449 `; 450 } 451 } 452 453 454const videosPosts = document.querySelector("#results"); 455const searchInput = document.querySelector(".iso-filter-quicksearch"); 456 457let proxyElem = document.createElement("div"); 458 459let currentSearchKeyword = ""; 460let infScroll; 461 462function getVideoPost({ title, date_posted, thumbnail, slug }) { 463 return ` 464 <div class="col"> 465 <div class="text-secondary fs-8 lh-sm"> 466 <a href="/videos/${slug}" class="text-decoration-none text-secondary"> 467 <div class="video-thumbnail mb-3 ratio ratio-16x9 position-relative"> 468 <img src="${thumbnail}" class="object-fit-cover img-fluid" alt="${title}" width="480" height="360" /> 469 <i class="bi bi-play-circle text-white position-absolute start-50 top-50 translate-middle d-flex justify-content-center align-items-center"></i> 470 </div> 471 <div class="d-flex justify-content-between"> 472 <div class="video-description-wrapper"> 473 <div class="video-title"> 474 <h2 class="fs-8 fw-bold">${title}</h2> 475 </div> 476 <div class="video-description-wrapper text-nowrap fs-4"> 477 <div class="video-date"> 478 <span>${date_posted}</span> 479 </div> 480 </div> 481 </div> 482 </div> 483 </a> 484 </div> 485 </div> 486 `; 487} 488 489function initInfiniteScroll(searchKeyword = "") { 490 if (infScroll) { 491 infScroll.destroy(); 492 } 493 494 infScroll = new InfiniteScroll(videosPosts, { 495 path() { 496 return searchKeyword 497 ? `https://pvl.ph/searchvideos` 498 : `https://pvl.ph/loadmorevideos`; 499 }, 500 responseBody: "json", 501 status: ".page-load-status", 502 scrollThreshold: 0, 503 history: false, 504 505 fetchOptions() { 506 let group_no = infScroll.loadCount + 1; 507 console.log("Fetching group:", group_no, " | Search:", searchKeyword); 508 509 return { 510 method: "POST", 511 headers: { 512 "Content-Type": "application/x-www-form-urlencoded", 513 }, 514 body: searchKeyword 515 ? `search=${encodeURIComponent(searchKeyword)}&group_no=${group_no}` 516 : `group_no=${group_no}`, 517 }; 518 }, 519 }); 520 521 infScroll.on("load", function (body) { 522 if (body.length !== 0) { 523 let itemsHTML = body.map(getVideoPost).join(""); 524 proxyElem.innerHTML = itemsHTML; 525 videosPosts.append(...proxyElem.children); 526 } else { 527 console.log("No more videos."); 528 infScroll.destroy(); 529 } 530 }); 531} 532 533// Initial scroll setup (default list) 534if (videosPosts) { 535 initInfiniteScroll(); 536} 537 538// Search functionality with debounce 539if (searchInput) { 540 let typingTimer; 541 const debounceTime = 500; 542 543 searchInput.addEventListener("keyup", function () { 544 clearTimeout(typingTimer); 545 typingTimer = setTimeout(() => { 546 currentSearchKeyword = this.value.trim(); 547 console.log("Searching for:", currentSearchKeyword); 548 549 videosPosts.innerHTML = ""; 550 551 fetch("https://pvl.ph/searchvideos", { 552 method: "POST", 553 headers: { "Content-Type": "application/x-www-form-urlencoded" }, 554 body: `search=${encodeURIComponent(currentSearchKeyword)}&group_no=0`, 555 }) 556 .then((res) => res.json()) 557 .then((data) => { 558 if (data.length) { 559 videosPosts.innerHTML = data.map(getVideoPost).join(""); 560 } else { 561 videosPosts.innerHTML = "<p>No results found</p>"; 562 } 563 564 // Reinitialize Infinite Scroll for new search 565 initInfiniteScroll(currentSearchKeyword); 566 }); 567 }, debounceTime); 568 }); 569} 570 571 572 573 // Infinite scroll gallery 574 const galleryPosts = document.querySelector(".additional-gallery-container"); 575 576 if (galleryPosts) { 577 //let currentRecord = galleryPosts.children.length; 578 //console.log(currentRecord); 579 let groupNo = 0; 580 581 let infScroll = new InfiniteScroll(galleryPosts, { 582 path: function () { 583 return "https://pvl.ph/loadmorephotos"; 584 }, 585 responseBody: "json", 586 status: ".page-load-status", 587 scrollThreshold: 0, 588 history: false, 589 fetchOptions: () => { 590 body = `group_no=${groupNo}`; 591 groupNo++; 592 return { 593 method: "POST", 594 headers: { 595 "Content-Type": "application/x-www-form-urlencoded", 596 }, 597 body: body, 598 }; 599 }, 600 }); 601 // use element to turn HTML string into elements 602 let proxyElem = document.createElement("div"); 603 604 infScroll.on("load", function (body) { 605 //console.log("Loaded batch:", body); 606 607 if (body.length !== 0) { 608 let itemsHTML = body.map(getGalleryPosts).join(""); 609 610 proxyElem.innerHTML = itemsHTML; 611 612 galleryPosts.append(...proxyElem.children); 613 } else { 614 //console.log("No more records."); 615 infScroll.destroy(); 616 } 617 }); 618 619 function getGalleryPosts({ title, thumbnail, date_created, slug, image }) { 620 const imgSrc = (thumbnail === "" || thumbnail === "undefined") ? image : thumbnail; 621 return ` 622 <div class="col"> 623 <div class="card text-white overflow-hidden"> 624 <a href="/gallery/${slug}" class="text-white"> 625 <div class="ratio ratio-4x3"> 626 <img src="${imgSrc}" class="card-img object-fit-cover img-fluid" alt="${title.replace(/_/g, " ")}" width="493" height="207"/> 627 </div>
628 <div class="card-img-overlay bg-gradient row row-cols-1 align-items-end"> 629 <div class="col"> 630 <h2 class="card-title fs-6 fw-bold mb-0">${title.replace(/_/g, " ")}</h2> 631 <span class="card-text fs-4 fw-bold">${date_created}</span> 632 </div> 633 </div> 634 </a> 635 </div> 636 </div> 637 `; 638 } 639 } 640 641 // Isotope Masonry 642 const announcementPosts = document.querySelector(".announcement-grid"); 643 644 if (announcementPosts) { 645 var iso = new Isotope(announcementPosts, { 646 itemSelector: ".grid-item", 647 getSortData: { 648 number: "[data-timestamp]", 649 }, 650 sortBy: "number", 651 sortAscending: announcementPosts.getAttribute("data-ascending") == "true" ? true : false, 652 }); 653 } 654 655 656 /****** Window scroll ******/ 657 $( window ).on( 'scroll', initScrollNavigate ); 658 659 /****** Window scroll function ******/ 660 function initScrollNavigate() { 661 662 var scrollPos = $( window ).scrollTop(); 663 664 /****** Scroll to top ******/ 665 if ( scrollPos > 150 ) { 666 $( '.scroll-top-arrow' ).fadeIn( '300' ); 667 } else { 668 $( '.scroll-top-arrow' ).fadeOut( '300' ); 669 } 670 } 671 /****** Scroll to top *****/ 672 $( document ).on( 'click', '.scroll-top-arrow', function () { 673 $( 'html, body' ).animate({ scrollTop: 0 }, 800 ); 674 return false; 675 }); 676 677 678 679})();
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.