1(function () { 2 function init() { 3 const root = document.querySelector('[data-component="cpm-corsi-desk"]'); 4 if (!root) return; 5 6 const list = root.querySelector(".cpm-corsi-desk__courses"); 7 const catsWrap = root.querySelector(".cpm-corsi-desk__cats"); 8 const subcatsWrap = root.querySelector(".cpm-corsi-desk__subcats"); 9 10 if (!list || !catsWrap || !subcatsWrap) return; 11 12 // prendo SEMPRE gli LI originali (li riuso e li sposto di DOM) 13 const items = Array.from(list.querySelectorAll(".cpm-corsi-desk__course-item")); 14 15 const catButtons = Array.from(root.querySelectorAll(".cpm-corsi-desk__cat-btn")); 16 const subcatButtons = () => Array.from(root.querySelectorAll(".cpm-corsi-desk__subcat-btn")); 17 18 if (!catButtons.length || !items.length) return; 19 20 // corsi NON visibili allâinizio 21 list.style.display = "none"; 22 23 function showCourses() { 24 list.style.display = ""; 25 } 26 function hideCourses() { 27 list.style.display = "none"; 28 } 29 30 function animateStart() { 31 root.classList.add("is-transitioning"); 32 root.classList.remove("is-show"); 33 } 34 35 function animateEnd() { 36 root.classList.add("is-show"); 37 window.setTimeout(() => root.classList.remove("is-transitioning"), 240); 38 } 39 40 function render(nodes) { 41 list.innerHTML = ""; 42 const frag = document.createDocumentFragment(); 43 nodes.forEach((node) => frag.appendChild(node)); 44 list.appendChild(frag); 45 } 46 47 // --- filtro per TERM ID (vale sia per categoria che per sottocategoria) 48 function courseHasTerm(item, termId) { 49 const raw = item.getAttribute("data-course-terms") || ""; 50 if (!raw) return false; 51 return raw 52 .split(",") 53 .map((s) => s.trim()) 54 .includes(String(termId)); 55 } 56 57 function setActive(buttons, btn, activeClass) { 58 buttons.forEach((b) => b.classList.remove(activeClass)); 59 if (btn) btn.classList.add(activeClass); 60 } 61 62 function applyFilterByTerm(termId) { 63 showCourses(); 64 animateStart(); 65 66 window.setTimeout(() => { 67 let matched = items.filter((item) => courseHasTerm(item, termId)); 68 69 matched.sort((a, b) => 70 (a.textContent || "").trim().localeCompare( 71 (b.textContent || "").trim(), 72 "it", 73 { sensitivity: "base" } 74 ) 75 ); 76 77 render(matched); 78 animateEnd(); 79 }, 120); 80 } 81 82 // --- gestione UI sottocategorie 83 function showSubcatsForCat(catId) { 84 // prendo tutte le subcat di quella categoria (già stampate dal PHP) 85 const all = Array.from(root.querySelectorAll('.cpm-corsi-desk__subcat-item')); 86 let any = false; 87 88 all.forEach(li => { 89 const parent = li.getAttribute("data-parent-cat"); 90 const visible = String(parent) === String(catId); 91 li.style.display = visible ? "" : "none"; 92 if (visible) any = true; 93 }); 94 95 // Mostro/nascondo contenitore subcats (se non ce ne sono, lo nascondo) 96 subcatsWrap.style.display = any ? "" : "none"; 97 return any; 98 } 99 100 // --- click categorie 101 catButtons.forEach((btn) => { 102 btn.addEventListener("click", function () { 103 const catId = this.getAttribute("data-cat-id"); 104 if (!catId) return; 105 106 setActive(catButtons, this, "active_cat"); 107 108 // reset stato subcat attiva 109 setActive(subcatButtons(), null, "active_subcat"); 110 111 const hasSubcats = showSubcatsForCat(catId); 112 113 if (hasSubcats) { 114 // Se ci sono sottocategorie: non mostro ancora i corsi 115 hideCourses(); 116 animateStart(); 117 window.setTimeout(() => animateEnd(), 120); 118 } else { 119 // Se non ci sono sottocategorie: filtro direttamente per categoria 120 applyFilterByTerm(catId); 121 } 122 }); 123 }); 124 125 // --- click sottocategorie (delegation, così funziona anche se WP fa cache/delay) 126 subcatsWrap.addEventListener("click", function (e) { 127 const btn = e.target.closest(".cpm-corsi-desk__subcat-btn"); 128 if (!btn) return; 129 130 const subId = btn.getAttribute("data-subcat-id"); 131 if (!subId) return; 132
133 setActive(subcatButtons(), btn, "active_subcat"); 134 applyFilterByTerm(subId); 135 }); 136 137 // AUTO-OPEN: prima categoria 138 // const firstCatBtn = catButtons[0]; 139 // if (firstCatBtn) { 140 // firstCatBtn.click(); 141 // } 142 } 143 144 window.CPM_CORSI_DESK_INIT = init; 145 146 if (document.readyState === "loading") { 147 document.addEventListener("DOMContentLoaded", init); 148 } else { 149 init(); 150 } 151})();
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.