Search code examples
angularmaterial-uiangular-material-paginator

how to enable prev and next button in pagination in material angular


I am experimenting with the material angular pagination where I send the number of data required by the table pagination from backend. For example, I have 7 records, the first page require five data to display. so it retrieve the first five data which is ok. Then, I go to second page it gives 2 data. But in this scenario, the prev and next button get disabled. I checked the page index, page size. all are ok. The pagination works correctly when I send all the data in a single request.

Template

<div class="mat-elevation-z8">
  <table mat-table [dataSource]="dataSource" matSort>

    <ng-container matColumnDef="photoPath">
      <th mat-header-cell *matHeaderCellDef> Photo </th>
      <td mat-cell *matCellDef="let element">
        <img [src]="element.photoPath" alt="Photo" width="50">
      </td>
    </ng-container>

    <ng-container matColumnDef="fullName">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Full Name </th>
      <td mat-cell *matCellDef="let element"> {{element.fullName}} </td>
    </ng-container>

    <ng-container matColumnDef="email">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
      <td mat-cell *matCellDef="let element"> {{element.email}} </td>
    </ng-container>

    <ng-container matColumnDef="dateOfBirth">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> DateOfBirth </th>
      <td mat-cell *matCellDef="let element"> {{element.dateOfBirth | date}} </td>
    </ng-container>

    <ng-container matColumnDef="mobile">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Mobile </th>
      <td mat-cell *matCellDef="let element"> {{element.mobile}} </td>
    </ng-container>

    <ng-container matColumnDef="action">
      <th mat-header-cell *matHeaderCellDef> Action </th>
      <td mat-cell *matCellDef="let element">
        <button mat-button color="primary" (click)="editEmployee(element.id)">Edit</button>
        <button mat-button color="warn" (click)="deleteEmployee(element.id)">Delete</button>
      </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>

  <mat-paginator [pageSizeOptions]="[5, 10, 20]"
               showFirstLastButtons
               [length]="totalRecords"  
               [pageSize]="searchValues.pageSize">
</mat-paginator>

class

export class DataTableComponent{
  totalRecords: number = 100; // Declare totalRecords here
  displayedColumns: string[] = ['photoPath','fullName', 'email', 'mobile','dateOfBirth','action'];
  Employee!: Employee[];
  dataSource = new MatTableDataSource<Employee>(this.Employee);

  @ViewChild(MatPaginator) paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  http = inject(HttpServiceService);
  router = inject(Router);
  dialog = inject(MatDialog);

 

  ngAfterViewInit() {
    // Now, the paginator is initialized, so we can safely load employees
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
    this.LoadEmployee(this.paginator.pageSize, this.paginator.pageIndex);
    this.paginator.page.subscribe((event: PageEvent) => {
      this.LoadEmployee(event.pageSize, event.pageIndex);
    });
    
  }
 LoadEmployee(pageSize: number, pageIndex: number) {
    this.http.GetAllEmployee(pageSize, pageIndex + 1).subscribe((response: any) => {
      this.dataSource.data = response.data.items;
      this.paginator.length = response.data.total;  // Set total number of records for paginator
      this.totalRecords = response.data.total; // Update totalRecords here
      this.paginator.pageSize = pageSize;
      console.log(this.paginator.pageSize, this.paginator.pageIndex, this.totalRecords)
    });
  }
  

Solution

  • The problem was solved by setting the pagination property directly to the HTML element. Html element change

    <mat-paginator [pageSizeOptions]="[5, 10, 20]"
                   showFirstLastButtons
                   [length]="totalRecords"  
                   [pageSize]="pageSize"
                   [pageIndex]="pageNumber"
                   (page)="changingPage($event)"
                   >
    </mat-paginator>
    

    in class, I add the property of the element and update it when the page event is called.

    totalRecords: number = 100; // Declare totalRecords here
      displayedColumns: string[] = ['photoPath','fullName', 'email', 'mobile','dateOfBirth','action'];
      Employee!: Employee[];
      dataSource = new MatTableDataSource<Employee>(this.Employee);
      pageSize = 5
      pageNumber = 0
      //@ViewChild(MatPaginator) paginator!: MatPaginator;
      @ViewChild(MatSort) sort!: MatSort;
    
      http = inject(HttpServiceService);
      router = inject(Router);
      dialog = inject(MatDialog);
    
     
    
      ngAfterViewInit() {
        // Now, the paginator is initialized, so we can safely load employees
        //this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
        this.LoadEmployee(this.pageSize, this.pageNumber);
      }
    
      changingPage(event:PageEvent){
        console.log(event)
        this.LoadEmployee(event.pageSize,event.pageIndex)
      }
    
    LoadEmployee(pageSize: number, pageIndex: number) {
        this.http.GetAllEmployee(pageSize, pageIndex + 1).subscribe((response: any) => {
          this.dataSource.data = response.data.items;
          this.totalRecords = response.data.total; // Update totalRecords here
          this.pageSize = pageSize;
          this.pageNumber = pageIndex      
        });
      }