Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Table pagination using Svelte

Tags:

svelte

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> 
like image 663
dariusz Avatar asked Oct 17 '25 11:10

dariusz


1 Answers

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.

like image 187
Thomas Hennes Avatar answered Oct 22 '25 07:10

Thomas Hennes