|
199 | 199 | }; |
200 | 200 |
|
201 | 201 | /* ========================================================== |
202 | | - 2. Category Filter Pills (homepage) |
| 202 | + 2. Category + JDK Dropdown Filters (homepage) |
203 | 203 | ========================================================== */ |
204 | 204 | const initFilters = () => { |
205 | | - const pills = document.querySelectorAll('#categoryFilter .filter-pill'); |
206 | 205 | const cards = document.querySelectorAll('.tip-card'); |
207 | | - if (!pills.length || !cards.length) return; |
| 206 | + if (!cards.length) return; |
208 | 207 |
|
209 | 208 | let activeCategory = null; |
210 | 209 | let activeJdk = null; |
|
234 | 233 | } |
235 | 234 | }; |
236 | 235 |
|
237 | | - pills.forEach(pill => { |
238 | | - pill.addEventListener('click', () => { |
239 | | - const category = pill.dataset.filter || 'all'; |
240 | | - const wasActive = pill.classList.contains('active'); |
241 | | - |
242 | | - // Update active pill (toggle off if re-clicked) |
243 | | - pills.forEach(p => p.classList.remove('active')); |
244 | | - if (!wasActive) pill.classList.add('active'); |
245 | | - |
246 | | - activeCategory = (!wasActive && category !== 'all') ? category : null; |
247 | | - |
248 | | - // Update URL hash to reflect active filter |
249 | | - if (activeCategory) { |
250 | | - history.replaceState(null, '', '#' + activeCategory); |
251 | | - } else { |
252 | | - history.replaceState(null, '', window.location.pathname + window.location.search); |
253 | | - } |
254 | | - |
255 | | - applyFilters(); |
256 | | - }); |
257 | | - }); |
258 | | - |
259 | | - // JDK Dropdown |
260 | | - const jdkDropdown = document.getElementById('jdkDropdown'); |
261 | | - if (jdkDropdown) { |
262 | | - const toggleBtn = jdkDropdown.querySelector('.jdk-dropdown-toggle'); |
263 | | - const labelEl = jdkDropdown.querySelector('.jdk-label'); |
264 | | - const list = jdkDropdown.querySelector('ul'); |
| 236 | + // Generic helper to wire up a dropdown |
| 237 | + const initDropdown = (dropdownEl, onSelect) => { |
| 238 | + if (!dropdownEl) return; |
| 239 | + const toggleBtn = dropdownEl.querySelector('.jdk-dropdown-toggle'); |
| 240 | + const labelEl = dropdownEl.querySelector('.jdk-label'); |
| 241 | + const list = dropdownEl.querySelector('ul'); |
265 | 242 |
|
266 | 243 | const openDropdown = () => { |
267 | 244 | list.style.display = 'block'; |
|
273 | 250 | toggleBtn.setAttribute('aria-expanded', 'false'); |
274 | 251 | }; |
275 | 252 |
|
| 253 | + const selectItem = (li) => { |
| 254 | + list.querySelectorAll('li').forEach(l => l.classList.remove('active')); |
| 255 | + li.classList.add('active'); |
| 256 | + if (labelEl) labelEl.textContent = li.textContent.trim(); |
| 257 | + }; |
| 258 | + |
276 | 259 | toggleBtn.addEventListener('click', (e) => { |
277 | 260 | e.stopPropagation(); |
278 | 261 | list.style.display === 'block' ? closeDropdown() : openDropdown(); |
|
287 | 270 | li.addEventListener('click', (e) => { |
288 | 271 | e.stopPropagation(); |
289 | 272 | closeDropdown(); |
| 273 | + selectItem(li); |
| 274 | + onSelect(li, toggleBtn); |
| 275 | + }); |
| 276 | + }); |
290 | 277 |
|
291 | | - const version = li.dataset.jdkFilter; |
292 | | - list.querySelectorAll('li').forEach(l => l.classList.remove('active')); |
293 | | - li.classList.add('active'); |
| 278 | + return { closeDropdown, setActive: (value) => { |
| 279 | + const target = list.querySelector(`li[data-filter="${value}"]`); |
| 280 | + if (target) { |
| 281 | + selectItem(target); |
| 282 | + toggleBtn.classList.toggle('has-filter', value !== 'all'); |
| 283 | + } |
| 284 | + }}; |
| 285 | + }; |
294 | 286 |
|
295 | | - activeJdk = version !== 'all' ? version : null; |
296 | | - if (labelEl) labelEl.textContent = li.textContent.trim(); |
297 | | - toggleBtn.classList.toggle('has-filter', !!activeJdk); |
| 287 | + // Category dropdown |
| 288 | + const categoryDropdown = document.getElementById('categoryDropdown'); |
| 289 | + const catDropdownCtrl = initDropdown(categoryDropdown, (li, toggleBtn) => { |
| 290 | + const category = li.dataset.filter; |
| 291 | + activeCategory = category !== 'all' ? category : null; |
| 292 | + toggleBtn.classList.toggle('has-filter', !!activeCategory); |
| 293 | + if (activeCategory) { |
| 294 | + history.replaceState(null, '', '#' + activeCategory); |
| 295 | + } else { |
| 296 | + history.replaceState(null, '', window.location.pathname + window.location.search); |
| 297 | + } |
| 298 | + applyFilters(); |
| 299 | + }); |
298 | 300 |
|
299 | | - applyFilters(); |
300 | | - }); |
301 | | - }); |
302 | | - } |
| 301 | + // JDK dropdown |
| 302 | + const jdkDropdown = document.getElementById('jdkDropdown'); |
| 303 | + initDropdown(jdkDropdown, (li, toggleBtn) => { |
| 304 | + const version = li.dataset.jdkFilter; |
| 305 | + activeJdk = version !== 'all' ? version : null; |
| 306 | + toggleBtn.classList.toggle('has-filter', !!activeJdk); |
| 307 | + applyFilters(); |
| 308 | + }); |
303 | 309 |
|
304 | 310 | // Apply filter from a given category string (or "all" / empty for no filter) |
305 | 311 | const applyHashFilter = (category) => { |
306 | | - const target = category |
307 | | - ? document.querySelector(`#categoryFilter .filter-pill[data-filter="${category}"]`) |
308 | | - : null; |
309 | | - if (target) { |
310 | | - target.click(); |
311 | | - // Scroll the filter section into view |
| 312 | + if (category && catDropdownCtrl) { |
| 313 | + catDropdownCtrl.setActive(category); |
| 314 | + activeCategory = category; |
| 315 | + applyFilters(); |
312 | 316 | const section = document.getElementById('all-comparisons'); |
313 | 317 | if (section) section.scrollIntoView({ behavior: 'smooth' }); |
314 | | - } else { |
315 | | - const allButton = document.querySelector('#categoryFilter .filter-pill[data-filter="all"]'); |
316 | | - if (allButton) allButton.click(); |
| 318 | + } else if (catDropdownCtrl) { |
| 319 | + catDropdownCtrl.setActive('all'); |
| 320 | + activeCategory = null; |
| 321 | + applyFilters(); |
317 | 322 | } |
318 | 323 | }; |
319 | 324 |
|
|
0 commit comments