js übernimmt Sortierung + Fallback
This commit is contained in:
+223
-22
@@ -1,27 +1,228 @@
|
||||
function initPaginator() {
|
||||
const form = document.getElementById('search-form-id');
|
||||
const pageInput = document.getElementById('s-res-page-input');
|
||||
const pageButtons = document.querySelectorAll('.s-res-page-navigation .s-res-page-btn');
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
pageButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
if (this.disabled) return;
|
||||
const state = {
|
||||
items: [],
|
||||
sorted: [],
|
||||
category: 'all',
|
||||
sort: 'alphabet',
|
||||
limit: 10,
|
||||
page: 1,
|
||||
};
|
||||
|
||||
const targetPage = this.getAttribute('data-page');
|
||||
function loadData() {
|
||||
const el = document.getElementById('s-res-data');
|
||||
if (!el) return [];
|
||||
try {
|
||||
return JSON.parse(el.textContent);
|
||||
} catch (e) {
|
||||
console.error('Suchergebnis-Daten konnten nicht gelesen werden', e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
if (targetPage && form && pageInput) {
|
||||
pageInput.value = targetPage;
|
||||
form.submit();
|
||||
}
|
||||
function applyFilterAndSort() {
|
||||
let list = state.items.slice();
|
||||
|
||||
if (state.category && state.category !== 'all') {
|
||||
list = list.filter(item => (item.category || '') === state.category);
|
||||
}
|
||||
|
||||
switch (state.sort) {
|
||||
case 'likes':
|
||||
list.sort((a, b) => (b.likes || 0) - (a.likes || 0));
|
||||
break;
|
||||
case 'newest':
|
||||
list.sort((a, b) => (b.creationDate || '').localeCompare(a.creationDate || ''));
|
||||
break;
|
||||
case 'oldest':
|
||||
list.sort((a, b) => (a.creationDate || '').localeCompare(b.creationDate || ''));
|
||||
break;
|
||||
default:
|
||||
list.sort((a, b) => (a.title || '').localeCompare(b.title || '', 'de', { sensitivity: 'base' }));
|
||||
}
|
||||
|
||||
state.sorted = list;
|
||||
const totalPages = Math.max(1, Math.ceil(state.sorted.length / state.limit));
|
||||
state.page = Math.min(Math.max(state.page, 1), totalPages);
|
||||
}
|
||||
|
||||
function el(tag, className, text) {
|
||||
const e = document.createElement(tag);
|
||||
if (className) e.className = className;
|
||||
if (text !== undefined) e.textContent = text;
|
||||
return e;
|
||||
}
|
||||
|
||||
function renderList() {
|
||||
const container = document.querySelector('.s-res-list');
|
||||
if (!container) return;
|
||||
|
||||
const start = (state.page - 1) * state.limit;
|
||||
const pageItems = state.sorted.slice(start, start + state.limit);
|
||||
|
||||
container.innerHTML = '';
|
||||
|
||||
if (pageItems.length === 0) {
|
||||
container.appendChild(el('p', null, 'Keine Beiträge zu diesem Suchbegriff gefunden.'));
|
||||
return;
|
||||
}
|
||||
|
||||
pageItems.forEach(item => {
|
||||
const item_el = el('div', 's-res-item');
|
||||
item_el.dataset.likes = item.likes;
|
||||
item_el.dataset.category = item.category;
|
||||
|
||||
const link = el('a', 's-res-link', item.title);
|
||||
link.href = 'index.php?pfad=showArticle&id=' + encodeURIComponent(item.id);
|
||||
|
||||
const title = el('h2', 's-res-item-title');
|
||||
title.appendChild(link);
|
||||
|
||||
const authorName = el('span', 's-res-author-name', item.author);
|
||||
const author = el('p', 's-res-author', 'Von: ');
|
||||
author.appendChild(authorName);
|
||||
|
||||
const likes = el('span', 's-res-likes', '❤️ ' + item.likes);
|
||||
|
||||
const metaRow = el('div', 's-res-meta-row');
|
||||
metaRow.appendChild(author);
|
||||
metaRow.appendChild(likes);
|
||||
|
||||
const content = el('div', 's-res-content');
|
||||
content.appendChild(title);
|
||||
content.appendChild(metaRow);
|
||||
|
||||
item_el.appendChild(content);
|
||||
item_el.appendChild(el('div', 's-res-arrow', '→'));
|
||||
|
||||
container.appendChild(item_el);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ist das DOM bereits vollständig aufgebaut?
|
||||
if (document.readyState === 'loading') {
|
||||
// Falls noch geladen wird, auf das Event warten
|
||||
document.addEventListener('DOMContentLoaded', initPaginator);
|
||||
} else {
|
||||
// Falls das HTML bereits komplett da ist, sofort ausführen
|
||||
initPaginator();
|
||||
}
|
||||
function renderMeta() {
|
||||
const metaEl = document.querySelector('.s-res-meta');
|
||||
const queryInput = document.getElementById('site-search');
|
||||
if (metaEl) {
|
||||
const q = queryInput ? queryInput.value : '';
|
||||
metaEl.textContent = state.sorted.length + ' Treffer für Ihre Suchanfrage "' + q + '"';
|
||||
}
|
||||
}
|
||||
|
||||
function renderPagination() {
|
||||
const nav = document.querySelector('.s-res-page-navigation');
|
||||
if (!nav) return;
|
||||
|
||||
const totalPages = Math.max(1, Math.ceil(state.sorted.length / state.limit));
|
||||
nav.innerHTML = '';
|
||||
|
||||
const makeBtn = (label, page, disabled, active) => {
|
||||
const btn = el('button', 's-res-page-btn' + (active ? ' is-active' : ''), label);
|
||||
btn.type = 'button';
|
||||
btn.disabled = !!disabled;
|
||||
btn.addEventListener('click', () => goToPage(page));
|
||||
return btn;
|
||||
};
|
||||
|
||||
nav.appendChild(makeBtn('«', state.page - 1, state.page <= 1));
|
||||
|
||||
const windowSize = 2;
|
||||
for (let p = 1; p <= totalPages; p++) {
|
||||
const edge = p === 1 || p === totalPages;
|
||||
const near = Math.abs(p - state.page) <= windowSize;
|
||||
if (!edge && !near) {
|
||||
if (p === 2 || p === totalPages - 1) nav.appendChild(el('span', 's-res-page-dots', '…'));
|
||||
continue;
|
||||
}
|
||||
nav.appendChild(makeBtn(String(p), p, false, p === state.page));
|
||||
}
|
||||
|
||||
nav.appendChild(makeBtn('»', state.page + 1, state.page >= totalPages));
|
||||
}
|
||||
|
||||
function updateUrl() {
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set('sort', state.sort);
|
||||
url.searchParams.set('category', state.category);
|
||||
url.searchParams.set('limit', state.limit);
|
||||
url.searchParams.set('page', state.page);
|
||||
window.history.replaceState(null, '', url);
|
||||
}
|
||||
|
||||
function rerender() {
|
||||
applyFilterAndSort();
|
||||
renderList();
|
||||
renderMeta();
|
||||
renderPagination();
|
||||
updateUrl();
|
||||
}
|
||||
|
||||
function goToPage(page) {
|
||||
const totalPages = Math.max(1, Math.ceil(state.sorted.length / state.limit));
|
||||
state.page = Math.min(Math.max(page, 1), totalPages);
|
||||
renderList();
|
||||
renderPagination();
|
||||
updateUrl();
|
||||
}
|
||||
|
||||
function initPaginator() {
|
||||
state.items = loadData();
|
||||
|
||||
const checkedSort = document.querySelector('.sort-radio:checked');
|
||||
state.sort = checkedSort ? checkedSort.value : 'alphabet';
|
||||
|
||||
const categorySelect = document.getElementById('category-filter');
|
||||
state.category = categorySelect ? categorySelect.value.toLowerCase() : 'all';
|
||||
|
||||
const limitSelect = document.getElementById('s-res-per-page');
|
||||
state.limit = limitSelect ? parseInt(limitSelect.value, 10) || 10 : 10;
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
state.page = parseInt(params.get('page') || '1', 10) || 1;
|
||||
|
||||
document.querySelectorAll('.sort-radio').forEach(radio => {
|
||||
radio.addEventListener('change', function () {
|
||||
state.sort = this.value;
|
||||
state.page = 1;
|
||||
rerender();
|
||||
});
|
||||
});
|
||||
|
||||
if (categorySelect) {
|
||||
categorySelect.addEventListener('change', function () {
|
||||
state.category = this.value.toLowerCase();
|
||||
state.page = 1;
|
||||
rerender();
|
||||
});
|
||||
}
|
||||
|
||||
if (limitSelect) {
|
||||
limitSelect.addEventListener('change', function () {
|
||||
state.limit = parseInt(this.value, 10) || 10;
|
||||
state.page = 1;
|
||||
rerender();
|
||||
});
|
||||
}
|
||||
|
||||
// "Filter anwenden"-Button wird bei aktivem JS nicht gebraucht
|
||||
const applyBtn = document.querySelector('.s-res-apply-btn');
|
||||
if (applyBtn) applyBtn.style.display = 'none';
|
||||
|
||||
// Server-gerenderte Pagination-Links durch clientseitige Steuerung ersetzen
|
||||
document.querySelectorAll('.s-res-page-navigation .s-res-page-btn').forEach(link => {
|
||||
link.addEventListener('click', function (evt) {
|
||||
evt.preventDefault();
|
||||
const target = parseInt(this.getAttribute('data-page'), 10);
|
||||
if (!isNaN(target)) goToPage(target);
|
||||
});
|
||||
});
|
||||
|
||||
rerender();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initPaginator);
|
||||
} else {
|
||||
initPaginator();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user