Add pagination with 'Näytä lisää' button (24 posts per page)
Shows 24 posts initially, loads 24 more each click. Resets on filter/search change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
<section class="controls" id="posts">
|
||||
<div class="container">
|
||||
<div class="search-row">
|
||||
<input type="text" id="search" data-i18n-ph="search_ph" oninput="filterPosts()" />
|
||||
<input type="text" id="search" data-i18n-ph="search_ph" oninput="visibleCount=POSTS_PER_PAGE;filterPosts()" />
|
||||
<button class="likes-filter-btn" id="likesFilterBtn" onclick="toggleLikesFilter()">❤️ Tykkäämäni</button>
|
||||
</div>
|
||||
<div class="filters" id="categoryFilters"></div>
|
||||
@@ -44,6 +44,9 @@
|
||||
<div class="container">
|
||||
<div class="recipe-grid" id="postGrid"></div>
|
||||
<p class="no-results" id="noResults" style="display:none;" data-i18n="no_results"></p>
|
||||
<div id="loadMoreWrap" style="text-align:center;margin:24px 0;display:none">
|
||||
<button id="loadMoreBtn" onclick="loadMore()" style="padding:10px 32px;font-size:1rem;border:2px solid #c4956a;background:#fff;color:#8b5e3c;border-radius:24px;cursor:pointer;font-weight:600">Näytä lisää</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
30
script.js
30
script.js
@@ -225,11 +225,15 @@ function shuffleArray(arr) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
const POSTS_PER_PAGE = 24;
|
||||
let visibleCount = POSTS_PER_PAGE;
|
||||
|
||||
function renderCards() {
|
||||
const grid = document.getElementById('postGrid');
|
||||
if (!grid) return;
|
||||
|
||||
shuffleArray(APP.posts);
|
||||
visibleCount = POSTS_PER_PAGE;
|
||||
grid.innerHTML = APP.posts.map(p => {
|
||||
const liked = APP.userLikes.includes(p.id);
|
||||
const likeCount = APP.likes[p.id] || 0;
|
||||
@@ -269,6 +273,7 @@ let currentSubFilter = 'all';
|
||||
function setFilter(category, btn) {
|
||||
currentFilter = category;
|
||||
currentSubFilter = 'all';
|
||||
visibleCount = POSTS_PER_PAGE;
|
||||
document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
renderSubFilters();
|
||||
@@ -277,6 +282,7 @@ function setFilter(category, btn) {
|
||||
|
||||
function setSubFilter(sub, btn) {
|
||||
currentSubFilter = sub;
|
||||
visibleCount = POSTS_PER_PAGE;
|
||||
document.querySelectorAll('.sub-filter-btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
filterPosts();
|
||||
@@ -297,7 +303,8 @@ function renderSubFilters() {
|
||||
function filterPosts() {
|
||||
const query = (document.getElementById('search')?.value || '').toLowerCase();
|
||||
const cards = document.querySelectorAll('.recipe-card');
|
||||
let visible = 0;
|
||||
let matched = 0;
|
||||
let shown = 0;
|
||||
cards.forEach(card => {
|
||||
const matchesCat = currentFilter === 'all' || card.dataset.category === currentFilter;
|
||||
const postSubs = (card.dataset.subcategory || '').split(',').filter(Boolean);
|
||||
@@ -309,12 +316,24 @@ function filterPosts() {
|
||||
const matchesSearch = !query || title.includes(query) || desc.includes(query) || subLbl.includes(query) || author.includes(query);
|
||||
const postId = card.querySelector('[data-like-id]')?.dataset.likeId || '';
|
||||
const matchesLikes = !APP.showOnlyLiked || APP.userLikes.includes(postId);
|
||||
const show = matchesCat && matchesSub && matchesSearch && matchesLikes;
|
||||
card.style.display = show ? '' : 'none';
|
||||
if (show) visible++;
|
||||
const matchesFilter = matchesCat && matchesSub && matchesSearch && matchesLikes;
|
||||
if (matchesFilter) {
|
||||
matched++;
|
||||
card.style.display = matched <= visibleCount ? '' : 'none';
|
||||
if (matched <= visibleCount) shown++;
|
||||
} else {
|
||||
card.style.display = 'none';
|
||||
}
|
||||
});
|
||||
const noRes = document.getElementById('noResults');
|
||||
if (noRes) noRes.style.display = visible === 0 ? 'block' : 'none';
|
||||
if (noRes) noRes.style.display = matched === 0 ? 'block' : 'none';
|
||||
const wrap = document.getElementById('loadMoreWrap');
|
||||
if (wrap) wrap.style.display = matched > shown ? '' : 'none';
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
visibleCount += POSTS_PER_PAGE;
|
||||
filterPosts();
|
||||
}
|
||||
|
||||
// ===========================
|
||||
@@ -930,6 +949,7 @@ async function init() {
|
||||
renderCategoryFilters();
|
||||
renderSubFilters();
|
||||
renderCards();
|
||||
filterPosts();
|
||||
|
||||
// Open post from URL hash (e.g. #resepti/pinaattiletut)
|
||||
const hash = window.location.hash;
|
||||
|
||||
Reference in New Issue
Block a user