/* Category filter bar enhancement (Proxify-style). * * Progressively enhances the existing category chip rows on the Events & * Projects, Blog and News pages into a single rounded pill bar with a trailing * search button. Clicking search swaps the tabs for a search input; typing * opens a results dropdown listing matching cards (thumbnail + category + * title). The existing chip elements keep their classes and data-attributes, * so the current filtering + pagination logic (main.js / blog-filter.js / * news-filter.js) keeps working unchanged. Filtering happens against the cards * already rendered on the page — no network calls. */ (function () { 'use strict'; function qsa(sel, root) { return [].slice.call((root || document).querySelectorAll(sel)); } function el(tag, cls) { var e = document.createElement(tag); if (cls) e.className = cls; return e; } function escapeHtml(s) { return String(s).replace(/[&<>"]/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"' }[c]; }); } // --- Localised strings ------------------------------------------------- var lang = (document.documentElement.getAttribute('lang') || 'en').toLowerCase(); if (lang === 'sl') lang = 'si'; if (['en', 'si', 'mk'].indexOf(lang) === -1) lang = 'en'; var I18N = { en: { ph: 'Search', none: 'No results found', count: function (n) { return n + ' result' + (n === 1 ? '' : 's') + ' found'; } }, si: { ph: 'Iskanje', none: 'Ni zadetkov', count: function (n) { return n + ' ' + (n === 1 ? 'zadetek' : 'zadetkov'); } }, mk: { ph: 'Пребарување', none: 'Нема резултати', count: function (n) { return n + ' ' + (n === 1 ? 'резултат' : 'резултати'); } } }; var t = I18N[lang]; // --- Per-page adapters ------------------------------------------------- // Each returns, for a card element, { href, title, img, icon, cat }. function projectItem(card, labelMap) { var link = card.querySelector('.post-link'); var titleEl = card.querySelector('.post-title'); var img = card.querySelector('.post-image'); if (!link || !titleEl) return null; return { href: link.getAttribute('href'), title: titleEl.textContent.trim(), img: img ? img.getAttribute('src') : '', cat: labelMap ? (labelMap[card.getAttribute('data-category')] || '') : '' }; } function blogItem(card) { var titleEl = card.querySelector('h3'); var tag = card.querySelector('.blog-tag'); var thumb = card.querySelector('.blog-thumb'); if (!titleEl) return null; return { href: card.getAttribute('href'), title: titleEl.textContent.trim(), icon: thumb ? thumb.innerHTML : '', cat: tag ? tag.textContent.trim() : '' }; } function newsItem(card) { var titleLink = card.querySelector('.newshub-body h3 a') || card.querySelector('h3 a'); var media = card.querySelector('.newshub-media'); var img = card.querySelector('.newshub-media img'); var badge = card.querySelector('.news-badge'); if (!titleLink) return null; return { href: media ? media.getAttribute('href') : titleLink.getAttribute('href'), title: titleLink.textContent.trim(), img: img ? img.getAttribute('src') : '', cat: badge ? badge.textContent.trim() : '' }; } var CONFIGS = [ { tabs: '.filter-nav', cards: '.posts-grid .post-card', item: projectItem, labels: true }, { tabs: '.blog-filters', cards: '.blog-grid .blog-card', item: blogItem }, { tabs: '.newshub-filters', cards: '.newshub-grid .newshub-card', item: newsItem } ]; CONFIGS.forEach(function (cfg) { var tabsEl = document.querySelector(cfg.tabs); if (tabsEl) upgrade(tabsEl, cfg); }); function upgrade(tabsEl, cfg) { // Map of data-filter -> visible label (projects only; used for result category chips). var labelMap = null; if (cfg.labels) { labelMap = {}; qsa('button', tabsEl).forEach(function (b) { labelMap[b.getAttribute('data-filter')] = b.textContent.trim(); }); } // Wrap the tabs row inside the new bar. var bar = el('div', 'filterbar'); tabsEl.parentNode.insertBefore(bar, tabsEl); tabsEl.classList.add('filterbar-tabs'); bar.appendChild(tabsEl); // Search icon button. var searchBtn = el('button', 'filterbar-search-btn'); searchBtn.type = 'button'; searchBtn.setAttribute('aria-label', t.ph); searchBtn.innerHTML = ''; bar.appendChild(searchBtn); // Search row (hidden until activated). var firstTab = tabsEl.querySelector('button, a'); var searchRow = el('div', 'filterbar-search'); searchRow.hidden = true; searchRow.innerHTML = '' + '
' + '
' + ''; searchRow.querySelector('.filterbar-search-label').textContent = firstTab ? firstTab.textContent.trim() : ''; var input = searchRow.querySelector('input'); input.placeholder = t.ph; bar.appendChild(searchRow); // Results dropdown. var results = el('div', 'filterbar-results'); results.hidden = true; results.innerHTML = '

'; bar.appendChild(results); var countEl = results.querySelector('.filterbar-results-count'); var listEl = results.querySelector('.filterbar-results-list'); function openSearch() { bar.classList.add('is-searching'); tabsEl.hidden = true; searchBtn.hidden = true; searchRow.hidden = false; input.value = ''; render(''); input.focus(); } function closeSearch() { bar.classList.remove('is-searching'); searchRow.hidden = true; results.hidden = true; tabsEl.hidden = false; searchBtn.hidden = false; } function render(q) { q = (q || '').trim().toLowerCase(); if (!q) { results.hidden = true; listEl.innerHTML = ''; countEl.textContent = ''; return; } var found = qsa(cfg.cards) .map(function (c) { return cfg.item(c, labelMap); }) .filter(function (it) { return it && it.title.toLowerCase().indexOf(q) !== -1; }); listEl.innerHTML = ''; countEl.textContent = found.length ? t.count(found.length) : t.none; found.forEach(function (it) { listEl.appendChild(resultRow(it)); }); results.hidden = false; } searchBtn.addEventListener('click', openSearch); searchRow.querySelector('.filterbar-search-close').addEventListener('click', closeSearch); input.addEventListener('input', function () { render(input.value); }); document.addEventListener('keydown', function (e) { if (e.key === 'Escape' && !searchRow.hidden) closeSearch(); }); document.addEventListener('click', function (e) { if (!bar.contains(e.target) && !searchRow.hidden) closeSearch(); }); } function resultRow(it) { var li = el('li', 'filterbar-result'); var a = el('a', 'filterbar-result-link'); a.href = it.href; var thumb = it.img ? '' : (it.icon || ''); a.innerHTML = '' + thumb + '' + '' + (it.cat ? '' + escapeHtml(it.cat) + '' : '') + '' + escapeHtml(it.title) + '' + ''; li.appendChild(a); return li; } })();