Files
PyPost/js/search.js
2025-10-05 19:52:43 +02:00

155 lines
5.2 KiB
JavaScript

function paginate_articles(page = 1) {
const articles = Array.from(document.querySelectorAll('article'));
if (!articles.length) return;
const query = document.getElementById('searchbox')?.value.toLowerCase() || '';
// Filter articles based on search
const filteredArticles = articles.filter(article =>
article.textContent.toLowerCase().includes(query)
);
const articlesPerPage = 5; // reduced to 5
const totalPages = Math.ceil(filteredArticles.length / articlesPerPage);
// Hide all articles first
articles.forEach(article => article.style.display = 'none');
// Show only articles for the current page
const start = (page - 1) * articlesPerPage;
const end = start + articlesPerPage;
filteredArticles.slice(start, end).forEach(article => article.style.display = 'block');
// Render pagination controls
renderPaginationControls(totalPages, page);
}
function renderPaginationControls(totalPages, currentPage) {
let paginationDiv = document.getElementById('pagination-controls');
let separator = document.getElementById('vertical-seperator');
const searchbox = document.getElementById('searchbox');
if (!searchbox) return;
if (!paginationDiv) {
paginationDiv = document.createElement('div');
paginationDiv.id = 'pagination-controls';
paginationDiv.style.display = 'inline-block';
paginationDiv.style.marginLeft = '16px';
paginationDiv.style.verticalAlign = 'middle';
const searchDiv = searchbox.parentNode;
const wrapper = document.createElement('div');
wrapper.style.display = 'flex';
wrapper.style.alignItems = 'center';
wrapper.style.gap = '12px';
searchDiv.appendChild(wrapper);
wrapper.appendChild(searchbox);
separator = document.createElement('div');
separator.id = "vertical-seperator";
separator.style.width = '1px';
separator.style.height = '28px';
separator.style.backgroundColor = '#ccc';
wrapper.appendChild(separator);
wrapper.appendChild(paginationDiv);
}
paginationDiv.innerHTML = '';
if (separator) separator.style.display = totalPages <= 1 ? 'none' : 'block';
if (totalPages <= 1) {
paginationDiv.style.display = 'none';
return;
} else {
paginationDiv.style.display = 'inline-flex';
paginationDiv.style.alignItems = 'center';
paginationDiv.style.gap = '6px';
}
// Previous button
const prevBtn = document.createElement('button');
prevBtn.textContent = '<';
prevBtn.disabled = currentPage === 1;
prevBtn.onclick = () => paginate_articles(currentPage - 1);
paginationDiv.appendChild(prevBtn);
// Page numbers
for (let i = 1; i <= totalPages; i++) {
const btn = document.createElement('button');
btn.textContent = i;
btn.disabled = i === currentPage;
btn.classList.add('page-number');
btn.onclick = () => paginate_articles(i);
paginationDiv.appendChild(btn);
}
// Next button
const nextBtn = document.createElement('button');
nextBtn.textContent = '>';
nextBtn.disabled = currentPage === totalPages;
nextBtn.onclick = () => paginate_articles(currentPage + 1);
paginationDiv.appendChild(nextBtn);
// Mobile current page span
let mobilePageSpan = document.getElementById('mobile-page-span');
if (!mobilePageSpan) {
mobilePageSpan = document.createElement('span');
mobilePageSpan.id = 'mobile-page-span';
mobilePageSpan.style.fontStyle = "italic"
mobilePageSpan.style.margin = '0 6px';
paginationDiv.appendChild(mobilePageSpan);
}
mobilePageSpan.textContent = `${currentPage}/${totalPages}`;
}
// Search input triggers pagination
function search_articles() {
paginate_articles(1);
}
// Setup search box & initial pagination
window.addEventListener('DOMContentLoaded', function() {
const searchDiv = document.createElement('div');
searchDiv.style.marginBottom = '16px';
searchDiv.style.paddingLeft = '19px';
searchDiv.innerHTML = `
<input
type="text"
id="searchbox"
placeholder="Search articles..."
style="
padding: 6px 6px 6px 28px;
font-size: 1em;
width: 220px;
background: url('../../css/icons/search.webp') no-repeat 6px center;
background-size: 20px 20px;
"
title="Search for articles"
/>
`;
// Insert after the h1 header but before "Available pages"
const availablePara = document.getElementById('available');
if (availablePara) {
availablePara.parentNode.insertBefore(searchDiv, availablePara);
} else {
// Fallback: insert at the beginning of main
const container = document.querySelector('main');
if (container && container.firstElementChild) {
container.insertBefore(searchDiv, container.firstElementChild);
}
}
const searchbox = document.getElementById('searchbox');
if (searchbox) {
searchbox.addEventListener('input', search_articles);
}
// Initial pagination setup
paginate_articles(1);
});