From f7e3382b103e0fad7acd00cd5d1dac138dfc77e3 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Wed, 3 Dec 2025 21:37:37 +0100 Subject: [PATCH] docs: update pagination documentation for server-side pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite pagination.md for server-side pagination approach - Update quick-start guide with new implementation pattern - Document shared pattern across Vendors, Companies, Users pages - Add examples for filters, search, and API integration πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../frontend/shared/pagination-quick-start.md | 291 +++++---- docs/frontend/shared/pagination.md | 566 ++++++++++-------- 2 files changed, 444 insertions(+), 413 deletions(-) diff --git a/docs/frontend/shared/pagination-quick-start.md b/docs/frontend/shared/pagination-quick-start.md index 22150f2d..bdf00515 100644 --- a/docs/frontend/shared/pagination-quick-start.md +++ b/docs/frontend/shared/pagination-quick-start.md @@ -1,201 +1,178 @@ -╔══════════════════════════════════════════════════════════════════╗ -β•‘ PAGINATION FEATURE - QUICK START β•‘ -β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• +# Pagination & Search - Quick Start Guide -✨ WHAT'S NEW -═════════════════════════════════════════════════════════════════ +## Overview -1. βœ… Edit Button - Pencil icon already present in table -2. βœ… Pagination - Smart pagination with 10 items per page -3. βœ… Page Navigation - Previous/Next buttons + page numbers -4. βœ… Smart Display - Shows "..." for large page ranges +All admin list pages use consistent **server-side pagination** with search and filters. +**Pages using this pattern:** +- `/admin/vendors` - Vendor Management +- `/admin/companies` - Company Management +- `/admin/users` - User Management -πŸ“¦ INSTALLATION (3 STEPS) -═════════════════════════════════════════════════════════════════ +--- -Step 1: Backup current files - $ cp templates/admin/vendors.html templates/admin/vendors.html.backup - $ cp static/admin/js/vendors.js static/admin/js/vendors.js.backup +## Visual Layout -Step 2: Replace with new versions - $ cp vendors.html templates/admin/vendors.html - $ cp vendors.js static/admin/js/vendors.js +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Page Title [+ Create Button] β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ [Stat 1] [Stat 2] [Stat 3] [Stat 4] ← Stats Cards β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ [πŸ” Search... ] [Filter β–Ό] [Filter β–Ό] [Refresh] ← Search Bar β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ Column 1 β”‚ Column 2 β”‚ Column 3 β”‚ Actions β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ Row 1 β”‚ ... β”‚ ... β”‚ πŸ‘ ✏️ πŸ—‘ β”‚ +β”‚ Row 2 β”‚ ... β”‚ ... β”‚ πŸ‘ ✏️ πŸ—‘ β”‚ +β”‚ ... β”‚ ... β”‚ ... β”‚ ... β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ Showing 1-10 of 45 ← 1 2 [3] 4 ... 9 β†’ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` -Step 3: Clear cache and test - - Hard refresh: Ctrl+Shift+R (Windows) or Cmd+Shift+R (Mac) - - Test with >10 vendors to see pagination +--- +## Key Features -🎨 VISUAL PREVIEW -═════════════════════════════════════════════════════════════════ +| Feature | Description | +|---------|-------------| +| Server-side pagination | Uses `skip`/`limit` API params | +| Debounced search | 300ms delay before API call | +| Filter dropdowns | Status, Verification, Role filters | +| Smart page numbers | Shows ellipsis for large page ranges | +| Refresh button | Manually reload data | +| Contextual empty state | Different message when filters applied | -Before (No Pagination): -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Vendor β”‚ Subdomain β”‚ Status β”‚ Created β”‚ Actions β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Vendor1β”‚ vendor1 β”‚ βœ“ β”‚ Jan 1 β”‚ πŸ‘ πŸ—‘ β”‚ ❌ No edit -β”‚ Vendor2β”‚ vendor2 β”‚ ⏰ β”‚ Jan 2 β”‚ πŸ‘ πŸ—‘ β”‚ -β”‚ ...50 more vendors... β”‚ -β”‚ Vendor52β”‚vendor52 β”‚ βœ“ β”‚ Jan 52 β”‚ πŸ‘ πŸ—‘ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -❌ All vendors on one page (hard to scroll through!) +--- +## State Structure -After (With Pagination): -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Vendor β”‚ Subdomain β”‚ Status β”‚ Created β”‚ Actions β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Vendor1β”‚ vendor1 β”‚ βœ“ β”‚ Jan 1 β”‚ πŸ‘ ✏️ πŸ—‘ β”‚ βœ… Edit added! -β”‚ Vendor2β”‚ vendor2 β”‚ ⏰ β”‚ Jan 2 β”‚ πŸ‘ ✏️ πŸ—‘ β”‚ -β”‚ ...8 more vendors... β”‚ -β”‚Vendor10β”‚ vendor10 β”‚ βœ“ β”‚ Jan 10 β”‚ πŸ‘ ✏️ πŸ—‘ β”‚ -β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ -β”‚ Showing 1-10 of 52 ← 1 [2] 3 4 5 ... 9 β†’ β”‚ βœ… Pagination! -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +### JavaScript State +```javascript +// Filters +filters: { + search: '', + is_active: '', // 'true', 'false', or '' + is_verified: '', // 'true', 'false', or '' +} +// Pagination +pagination: { + page: 1, + per_page: 10, + total: 0, + pages: 0 +} +``` -🎯 ACTION BUTTONS (3 BUTTONS PER ROW) -═════════════════════════════════════════════════════════════ +--- -1. πŸ‘ View (Blue) ─────────→ View vendor details -2. ✏️ Edit (Purple) ⭐ NEW β†’ Edit vendor form -3. πŸ—‘ Delete (Red) ────────→ Delete with confirmation +## Computed Properties +| Property | Purpose | +|----------|---------| +| `totalPages` | Total number of pages | +| `startIndex` | First item number on current page | +| `endIndex` | Last item number on current page | +| `pageNumbers` | Array of page numbers with '...' | -πŸ”’ PAGINATION CONTROLS -═════════════════════════════════════════════════════════════ +--- -Page 1 of 10: - [←] 1 2 3 4 5 ... 9 10 [β†’] - ^ ^ ^ ^ ^ - | | | | └─ Next button - | | | └──── Last page - | | └─────── Ellipsis (...) - | └───────────────────── Page numbers - └──────────────────────── Previous button (disabled) +## Methods -Page 5 of 10: - [←] 1 ... 4 [5] 6 ... 10 [β†’] - ↑ ↑ ↑ - | | └─ Next page - | └───── Current page (purple) - └───────── Previous pages +| Method | Purpose | +|--------|---------| +| `debouncedSearch()` | Triggers search after 300ms | +| `previousPage()` | Go to previous page | +| `nextPage()` | Go to next page | +| `goToPage(num)` | Jump to specific page | +--- -πŸ“Š HOW IT WORKS -═════════════════════════════════════════════════════════════ +## Page Number Display -1. Template displays: paginatedVendors (not all vendors) -2. Alpine.js computes: Which 10 vendors to show -3. User clicks page: currentPage updates -4. Template refreshes: Shows new 10 vendors +**Few pages (7 or less):** +``` +← 1 2 3 4 5 6 7 β†’ +``` -Simple and reactive! πŸŽ‰ +**Many pages, at start:** +``` +← [1] 2 3 ... 10 β†’ +``` +**Many pages, in middle:** +``` +← 1 ... 4 [5] 6 ... 10 β†’ +``` -βš™οΈ CONFIGURATION -═════════════════════════════════════════════════════════════ +**Many pages, at end:** +``` +← 1 ... 8 9 [10] β†’ +``` -Change items per page in vendors.js: +--- -// Find this line: -itemsPerPage: 10, +## API Integration -// Change to any number: -itemsPerPage: 25, // Show 25 per page -itemsPerPage: 50, // Show 50 per page +### Request +``` +GET /admin/vendors?skip=0&limit=10&search=acme&is_active=true +``` +### Response +```json +{ + "vendors": [...], + "total": 45, + "skip": 0, + "limit": 10 +} +``` -πŸ§ͺ TESTING CHECKLIST -═════════════════════════════════════════════════════════════ +--- -After installation: +## Configuration -β–‘ Vendors page loads -β–‘ If <10 vendors: No pagination shows (correct!) -β–‘ If >10 vendors: Pagination appears -β–‘ Can click page numbers to navigate -β–‘ Can click ← β†’ arrows -β–‘ "Showing X-Y of Z" updates correctly -β–‘ Edit button (pencil icon) appears -β–‘ Edit button navigates to edit page -β–‘ View button still works -β–‘ Delete button still works -β–‘ Dark mode works -β–‘ Pagination styling matches theme +### Change Items Per Page +Edit in JavaScript file: +```javascript +pagination: { + page: 1, + per_page: 25, // Change from 10 + total: 0, + pages: 0 +} +``` -🎨 FEATURES -═════════════════════════════════════════════════════════════ +--- -βœ… Smart pagination (10 per page) -βœ… Edit button added (purple pencil) -βœ… Dynamic page numbers with "..." -βœ… Previous/Next disabled at boundaries -βœ… Shows "X-Y of Total" count -βœ… Dark mode compatible -βœ… Windmill theme styling -βœ… Fully responsive -βœ… Client-side pagination (fast!) -βœ… Auto-reset to page 1 after data reload +## Files Reference +| Page | Template | JavaScript | +|------|----------|------------| +| Vendors | `templates/admin/vendors.html` | `static/admin/js/vendors.js` | +| Companies | `templates/admin/companies.html` | `static/admin/js/companies.js` | +| Users | `templates/admin/users.html` | `static/admin/js/users.js` | -πŸ’‘ TIPS -═════════════════════════════════════════════════════════════ +--- -1. Need more vendors per page? - Change itemsPerPage in vendors.js +## Adding to a New Page -2. Want server-side pagination? - For 1000+ vendors, consider API pagination +1. **Add state** to JavaScript: +```javascript +filters: { search: '', is_active: '' }, +pagination: { page: 1, per_page: 10, total: 0, pages: 0 } +``` -3. Want to preserve page on refresh? - Add localStorage for currentPage +2. **Add computed properties**: `totalPages`, `startIndex`, `endIndex`, `pageNumbers` -4. Want to add search/filter? - Filter vendors array first, then paginate +3. **Add methods**: `debouncedSearch()`, `previousPage()`, `nextPage()`, `goToPage()` -5. Page numbers look weird? - Check you have enough vendors (need >10 to see pagination) +4. **Update load function** to use query params +5. **Add HTML** for search bar and pagination footer -πŸ†˜ TROUBLESHOOTING -═════════════════════════════════════════════════════════════ - -Problem: Pagination not showing -β†’ Need more than 10 vendors to see it -β†’ Check itemsPerPage value - -Problem: Edit button doesn't work -β†’ Check backend route exists: /admin/vendors/{code}/edit -β†’ Check browser console for errors - -Problem: Page numbers stuck -β†’ Clear browser cache (Ctrl+Shift+R) -β†’ Check Alpine.js loaded correctly - -Problem: "Showing 0-0 of 0" -β†’ Vendors not loading from API -β†’ Check API endpoint /admin/vendors - - -πŸ“ FILES INCLUDED -═════════════════════════════════════════════════════════════ - -vendors.html ................. Updated template with pagination -vendors.js ................... Updated script with pagination logic -PAGINATION_DOCUMENTATION.md .. Full technical documentation -PAGINATION_QUICK_START.txt ... This file (quick reference) - - -πŸ“– LEARN MORE -═════════════════════════════════════════════════════════════ - -For detailed technical explanation, see: -β†’ PAGINATION_DOCUMENTATION.md - - -══════════════════════════════════════════════════════════════ - Pagination made easy! πŸ“–βœ¨ -══════════════════════════════════════════════════════════════ +See `docs/frontend/shared/pagination.md` for full implementation details. diff --git a/docs/frontend/shared/pagination.md b/docs/frontend/shared/pagination.md index 13b82521..0ac06631 100644 --- a/docs/frontend/shared/pagination.md +++ b/docs/frontend/shared/pagination.md @@ -1,297 +1,351 @@ -# Vendor Page Pagination Implementation +# Admin List Pages - Pagination & Search Implementation -## 🎯 What's New +## Overview -Your vendors page now includes: -1. βœ… **Edit button** - Already present (pencil icon next to view icon) -2. βœ… **Pagination** - New pagination controls at the bottom of the table +All admin list pages (Vendors, Companies, Users) share a consistent pagination and search pattern using **server-side pagination** with Alpine.js. --- -## πŸ“¦ Files Updated +## Files Using This Pattern -### 1. vendors.html -**Changes:** -- Changed `x-for="vendor in vendors"` β†’ `x-for="vendor in paginatedVendors"` -- Added pagination footer with controls -- Added "Showing X-Y of Z" results display - -### 2. vendors.js -**Changes:** -- Added pagination state: `currentPage`, `itemsPerPage` -- Added computed properties: - - `paginatedVendors` - Returns current page's vendors - - `totalPages` - Calculates total number of pages - - `startIndex` / `endIndex` - For "Showing X-Y" display - - `pageNumbers` - Generates smart page number array with ellipsis -- Added pagination methods: - - `goToPage(page)` - Navigate to specific page - - `nextPage()` - Go to next page - - `previousPage()` - Go to previous page +| Page | HTML Template | JavaScript | +|------|---------------|------------| +| Vendors | `templates/admin/vendors.html` | `static/admin/js/vendors.js` | +| Companies | `templates/admin/companies.html` | `static/admin/js/companies.js` | +| Users | `templates/admin/users.html` | `static/admin/js/users.js` | --- -## 🎨 Pagination Features +## State Structure -### Smart Page Number Display -The pagination intelligently shows page numbers: +### Filters Object +```javascript +filters: { + search: '', // Search query string + is_active: '', // 'true', 'false', or '' (all) + is_verified: '' // 'true', 'false', or '' (all) - vendors/companies only + role: '' // 'admin', 'vendor', or '' (all) - users only +} +``` -**Example 1: Few pages (≀7)** +### Pagination Object +```javascript +pagination: { + page: 1, // Current page number + per_page: 10, // Items per page + total: 0, // Total items from API + pages: 0 // Total pages (calculated) +} +``` + +--- + +## Computed Properties + +All three pages implement these computed properties: + +### `paginatedVendors` / `paginatedCompanies` / `users` +Returns the items array (already paginated from server): +```javascript +get paginatedVendors() { + return this.vendors; +} +``` + +### `totalPages` +```javascript +get totalPages() { + return this.pagination.pages; +} +``` + +### `startIndex` +```javascript +get startIndex() { + if (this.pagination.total === 0) return 0; + return (this.pagination.page - 1) * this.pagination.per_page + 1; +} +``` + +### `endIndex` +```javascript +get endIndex() { + const end = this.pagination.page * this.pagination.per_page; + return end > this.pagination.total ? this.pagination.total : end; +} +``` + +### `pageNumbers` +Generates smart page number array with ellipsis: +```javascript +get pageNumbers() { + const pages = []; + const totalPages = this.totalPages; + const current = this.pagination.page; + + if (totalPages <= 7) { + for (let i = 1; i <= totalPages; i++) { + pages.push(i); + } + } else { + pages.push(1); + if (current > 3) pages.push('...'); + + const start = Math.max(2, current - 1); + const end = Math.min(totalPages - 1, current + 1); + for (let i = start; i <= end; i++) { + pages.push(i); + } + + if (current < totalPages - 2) pages.push('...'); + pages.push(totalPages); + } + return pages; +} +``` + +--- + +## Methods + +### `debouncedSearch()` +Triggers search after 300ms delay: +```javascript +debouncedSearch() { + if (this._searchTimeout) { + clearTimeout(this._searchTimeout); + } + this._searchTimeout = setTimeout(() => { + this.pagination.page = 1; + this.loadVendors(); // or loadCompanies(), loadUsers() + }, 300); +} +``` + +### Pagination Methods +```javascript +previousPage() { + if (this.pagination.page > 1) { + this.pagination.page--; + this.loadVendors(); + } +} + +nextPage() { + if (this.pagination.page < this.totalPages) { + this.pagination.page++; + this.loadVendors(); + } +} + +goToPage(pageNum) { + if (pageNum !== '...' && pageNum >= 1 && pageNum <= this.totalPages) { + this.pagination.page = pageNum; + this.loadVendors(); + } +} +``` + +--- + +## API Integration + +### Building Query Parameters +```javascript +async loadVendors() { + const params = new URLSearchParams(); + params.append('skip', (this.pagination.page - 1) * this.pagination.per_page); + params.append('limit', this.pagination.per_page); + + if (this.filters.search) { + params.append('search', this.filters.search); + } + if (this.filters.is_active !== '') { + params.append('is_active', this.filters.is_active); + } + if (this.filters.is_verified !== '') { + params.append('is_verified', this.filters.is_verified); + } + + const response = await apiClient.get(`/admin/vendors?${params}`); + + this.vendors = response.vendors; + this.pagination.total = response.total; + this.pagination.pages = Math.ceil(response.total / this.pagination.per_page); +} +``` + +### API Response Format +```json +{ + "vendors": [...], + "total": 45, + "skip": 0, + "limit": 10 +} +``` + +--- + +## HTML Template Structure + +### Search & Filters Bar +```html +
+
+ +
+
+ + + + +
+
+ + +
+ + + + + +
+
+
+``` + +### Pagination Footer +```html +
+ + + Showing - + of + + + + + + + +
+``` + +--- + +## Page Number Display Examples + +**Few pages (<=7):** ``` ← 1 2 3 4 5 6 7 β†’ ``` -**Example 2: Many pages, current = 1** +**Many pages, current = 1:** ``` -← 1 2 3 ... 9 10 β†’ +← [1] 2 3 ... 10 β†’ ``` -**Example 3: Many pages, current = 5** +**Many pages, current = 5:** ``` -← 1 ... 4 5 6 ... 10 β†’ +← 1 ... 4 [5] 6 ... 10 β†’ ``` -**Example 4: Many pages, current = 10** +**Many pages, current = 10:** ``` -← 1 ... 8 9 10 β†’ -``` - -### Configurable Items Per Page -Default: 10 vendors per page - -To change, edit in `vendors.js`: -```javascript -itemsPerPage: 10, // Change this number +← 1 ... 8 9 [10] β†’ ``` --- -## πŸ”§ How It Works +## Visual Layout -### 1. Computed Properties (Alpine.js) -Alpine.js computes these values reactively: - -```javascript -get paginatedVendors() { - const start = (this.currentPage - 1) * this.itemsPerPage; - const end = start + this.itemsPerPage; - return this.vendors.slice(start, end); -} ``` - -When `currentPage` changes, `paginatedVendors` automatically updates! - -### 2. Template Binding -The HTML template uses the computed property: -```html - -``` - -### 3. Pagination Controls -Buttons call the pagination methods: -```html -