I'm starting working on the project built in Svelte and never worked with Svelte before. I'm building the table with pagination and the issue I've got at the moment is that I don't know how can I implement pagination buttons working to display different rows. Any suggestions what I should do in the next steps?
<script>
import { onMount } from "svelte";
import Header from "./components/Header.svelte";
import Row from "./components/Row.svelte";
import Footer from "./components/Footer.svelte";
import Overlay from "./components/Overlay.svelte";
let rows = [];
let page = 0;
let totalPages = [];
let currentPageRows = [];
let itemsPerPage = 5;
let loading = true;
const paginate = (items) => {
const pages = Math.ceil(items.length / itemsPerPage);
const paginatedItems = Array.from({ length: pages }, (_, index) => {
const start = index * itemsPerPage;
return items.slice(start, start + itemsPerPage);
});
console.log("paginatedItems are", paginatedItems);
totalPages = [...paginatedItems];
currentPageRows = paginatedItems[page];
};
onMount(() => {
fetch("devapi/accountStatement/transactions.json")
.then((response) => {
if (response.ok) {
return response.json();
}
throw Error(response.status);
})
.then((data) => {
rows = data;
paginate(data);
loading = false;
})
.catch((error) => {
console.log(error);
});
});
const nextPageHandler = () => {
if (page < totalPages.length) {
page += 1;
}
console.log("page is", page);
};
const previousPageHandler = () => {
if (page > 0) {
page -= 1;
}
console.log("page is", page);
};
</script>
<table class="table table-bordered table-striped table-hover">
<Header />
<tbody>
{#if loading}
<Overlay />
{/if}
{#each currentPageRows as row, i}
<Row {row} />
{:else}
<tr>
<td colspan="100%">
<h5 class="text-center">There is no data to display here.</h5>
</td>
</tr>
{/each}
</tbody>
<Footer />
</table>
<nav class="pagination">
<ul>
<li>
<button
type="button"
class="btn-next-prev"
on:click={() => previousPageHandler()}
>PREV
</button>
</li>
{#each totalPages as page, i}
<li>
<button type="button" class="btn-page-number">{i + 1}</button>
</li>
{/each}
<li>
<button
type="button"
class="btn-next-prev"
on:click={() => nextPageHandler()}
>NEXT
</button>
</li>
</ul>
</nav>
You were almost there. What you want to do is bring in Svelte's reactive statements, making currentPageRows dependent on the current value of page.
You can do this with a single line of code:
...
let rows = [];
let page = 0;
let totalPages = [];
let currentPageRows = [];
let itemsPerPage = 5;
let loading = true;
$: currentPageRows = totalPages.length > 0 ? totalPages[page] : [];
const paginate = (items) => {
...
}
...
You could also simplify your handling of page navigation with a single function:
const setPage = (p) => {
if (p >= 0 && p < totalPages.length) {
page = p;
}
}
And use this function in all your on:click event handlers:
<nav class="pagination">
<ul>
<li>
<button
type="button"
class="btn-next-prev"
on:click={() => setPage(page - 1)}
>
PREV
</button>
</li>
{#each totalPages as page, i}
<li>
<button
type="button"
class="btn-page-number"
on:click={() => setPage(i)}
>
{i + 1}
</button>
</li>
{/each}
<li>
<button
type="button"
class="btn-next-prev"
on:click={() => setPage(page + 1)}
>
NEXT
</button>
</li>
</ul>
</nav>
See this REPL for a stripped down example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With