Skip to content

Instantly share code, notes, and snippets.

@Arifursdev
Last active December 18, 2024 11:55
Show Gist options
  • Save Arifursdev/9fa9d7f25e07aa7378324baa6bc82bea to your computer and use it in GitHub Desktop.
Save Arifursdev/9fa9d7f25e07aa7378324baa6bc82bea to your computer and use it in GitHub Desktop.
Pagination with Alpine.js
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Pagination with Alpine.js</title>
    <script
      src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js"
      defer
    ></script>
  </head>

  <body>
    <div class="dashboard" x-data="dashboard" x-init="init">
      <!-- Items Wrapper -->
      <div class="items-wrapper">
        <template x-for="item in items" :key="item.id">
          <div class="item" x-text="item.name"></div>
        </template>
      </div>

      <!-- Pagination Wrapper -->
      <div class="pagination-wrapper">
        <button
          class="pagination-btn pagination-btn__prev"
          x-on:click="prevPage"
          :disabled="current_page === 1"
        >
          Prev
        </button>

        <div class="pagination-numbers">
          <template x-for="page in pagesToShow" :key="page">
            <button
              type="button"
              x-on:click="goToPage(page)"
              x-text="page"
              :class="{'active': current_page === page}"
            ></button>
          </template>
        </div>

        <button
          class="pagination-btn pagination-btn__next"
          x-on:click="nextPage"
          :disabled="current_page === total_pages"
        >
          Next
        </button>
      </div>
    </div>

    <script>
      document.addEventListener("alpine:init", () => {
        Alpine.data("dashboard", () => ({
            
          itemsFromServer: [
            {
              id: 1,
              name: "Item 1",
            },
            {
              id: 2,
              name: "Item 2",
            },
            {
              id: 3,
              name: "Item 3",
            },
            {
              id: 4,
              name: "Item 4",
            },
            {
              id: 5,
              name: "Item 5",
            },
            {
              id: 6,
              name: "Item 6",
            },
            {
              id: 7,
              name: "Item 7",
            },
            {
              id: 8,
              name: "Item 8",
            },
            {
              id: 9,
              name: "Item 9",
            },
            {
              id: 10,
              name: "Item 10",
            },
          ],

          items: [],
          total_items: 0,
          total_pages: 0,
          current_page: 1,
          items_per_page: 3,

          fetchItems() {
            const startIndex = (this.current_page - 1) * this.items_per_page;
            const endIndex = startIndex + this.items_per_page;
            this.items = this.itemsFromServer.slice(startIndex, endIndex);

            // Update total items and total pages after fetching data from server by passing 'current_page' and 'items_per_page' as query parameters and handle the query and return the data accordingly

            this.total_items = this.itemsFromServer.length;
            this.total_pages = Math.ceil(
              this.total_items / this.items_per_page
            );
          },

          goToPage(page) {
            this.current_page = page;
            this.fetchItems();
          },
          prevPage() {
            if (this.current_page > 1) {
              this.current_page--;
              this.fetchItems();
            }
          },
          nextPage() {
            if (this.current_page < this.total_pages) {
              this.current_page++;
              this.fetchItems();
            }
          },
          pagesToShow() {
            const pages = [];
            let startPage = Math.max(1, this.current_page - 1);
            let endPage = Math.min(this.total_pages, startPage + 2);

            if (this.current_page === 1 || this.current_page === 2) {
              startPage = 1;
              endPage = Math.min(3, this.total_pages);
            }

            if (this.current_page === this.total_pages) {
              startPage = Math.max(1, this.total_pages - 2);
              endPage = this.total_pages;
            }

            for (let i = startPage; i <= endPage; i++) {
              pages.push(i);
            }

            return pages;
          },

          init() {
            this.fetchItems();
          },

        }));
      });
    </script>
  </body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment