paginate.component.ts (2343B)
1 import { Component, input, computed, inject } from '@angular/core'; 2 import { CommonModule } from '@angular/common'; 3 import { Router, ActivatedRoute } from '@angular/router'; 4 5 @Component({ 6 selector: 'div.pagination', 7 templateUrl: './paginate.component.html', 8 styleUrls: ['./paginate.component.scss'], 9 standalone: true, 10 imports: [CommonModule], 11 }) 12 export class PaginateComponent { 13 private router = inject(Router); 14 private route = inject(ActivatedRoute); 15 16 // Inputs from parent 17 readonly totalPages = input.required<number>(); 18 readonly total = input.required<number>(); 19 readonly page = input.required<number>(); 20 readonly pageSize = input.required<number>(); 21 22 // Available page sizes 23 readonly pageSizes = [10, 20, 50, 100]; 24 25 // Computed properties 26 readonly canGoPrevious = computed(() => this.page() > 1); 27 readonly canGoNext = computed(() => this.page() < this.totalPages()); 28 readonly startItem = computed(() => (this.page() - 1) * this.pageSize() + 1); 29 readonly endItem = computed(() => Math.min(this.page() * this.pageSize(), this.total())); 30 31 // Update URL query params - Angular inputs will auto-update from URL changes 32 private navigate(page: number, pageSize = this.pageSize()): void { 33 this.router.navigate([], { 34 relativeTo: this.route, 35 queryParams: { page, pageSize }, 36 queryParamsHandling: 'merge', 37 }); 38 } 39 40 // Get visible page numbers with smart ellipsis 41 getVisiblePages(): (number | string)[] { 42 const total = this.totalPages(); 43 const current = this.page(); 44 45 if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1); 46 47 const pages: (number | string)[] = [1]; 48 49 if (current <= 4) { 50 pages.push(...[2, 3, 4, 5], '...', total); 51 } else if (current >= total - 3) { 52 pages.push('...', ...Array.from({ length: 5 }, (_, i) => total - 4 + i)); 53 } else { 54 pages.push('...', current - 1, current, current + 1, '...', total); 55 } 56 57 return pages; 58 } 59 60 // Navigation methods 61 goToPage(page: number): void { 62 if (page >= 1 && page <= this.totalPages()) { 63 this.navigate(page); 64 } 65 } 66 67 onPageSizeChange(event: Event): void { 68 const size = +(event.target as HTMLSelectElement).value; 69 if (this.pageSizes.includes(size)) { 70 this.navigate(1, size); // Reset to page 1 when changing page size 71 } 72 } 73 }