Philip Mutua
Philip Mutua

Reputation: 6871

Customizing mat-paginator in angular material

I have implemented pagination on the server side in one of the endpoints and the response is as shown below. I want to implement pagination in Angular material I have the table already and I want to customize the <mat-paginator> component so that it can accommodate the response. How can I achieve this?

{
    "success": true,
    "msg": "success",
    "data": {
        "count": 1562,
        "total_pages": 16,
        "next": "http://localhost:7000/api/business_list/?page=4",
        "previous": "http://localhost:7000/api/business_list/?page=2",
        "results": [{
            "id": 37,
            "status": 2,
            "date_issued": "2020-09-09",
            "business_name": "Derox corp",
            "business_activity": "electronics",
            "business_id": "190000",
            "calendar_year": 2020,
        }]
    }
}

HTML

<ul class="breadcrumb">
  <li><a routerLink="/liquor/dashboard">DashBoard</a></li>
  <li>Business Permit</li>
  <li>All Businesses</li>
</ul>
<mat-toolbar matTooltip="Shows list of businesses" matTooltipPosition="above">Businesses</mat-toolbar>
<div class="row">
  <div class="col-sm-12">
    <div class="card min-vh-100 ">
      <div class="card-body p-4">
        <!-- <h4 class="card-title">Permits</h4> -->
        <h6 class="card-subtitle">A list of all available liquor businesses recorded int the system</h6>

        <div style="width:100%;">
          <div class="example-button-row">
            <!-- <button class="mat-raised-button btn btn-primary" color="accent"
              matTooltip="Click to add a new license application." (click)="onClickAddPermit()">
              Add
            </button> -->

            <button class="btn btn-success text-white" mat-raised-button
              (click)="exporter.exportTable('xlsx', {fileName:'test', sheet: 'sheet_name', Props: {Author: 'Talha'}})"
              matTooltip="Export data in excel format.">Export</button>

            <div class="row" style="margin:10px;">
              <mat-form-field class="search-form-field" floatLabel="never" matTooltip="search license application.">
                <input matInput [(ngModel)]="searchKey" placeholder="Search" autocomplete="off" (keyup)="applyFilter()">
                <mat-icon matSuffix>search</mat-icon>
                <button mat-button matSuffix mat-icon-button arial-label="Clear" *ngIf="searchKey"
                  (click)="onSearchClear()">
                  <mat-icon>close</mat-icon>
                </button>
              </mat-form-field>

            </div>


          </div>
          <mat-card style="padding-left:40px;padding-right:40px; padding-top:10px">

            <div class="mat-elavation-z8">
              <table class="col-md-12 table table-striped thead-dark" mat-table matTableExporter [dataSource]="listData"
                #exporter="matTableExporter" matSort>

                <ng-container matColumnDef="business_name">
                  <mat-header-cell *matHeaderCellDef mat-sort-header>Business Name</mat-header-cell>
                  <mat-cell *matCellDef="let element" class="truncate-cell"><span class="truncate-text"
                      matTooltip="{{element.business_name}}">{{element.business_name}}</span>
                  </mat-cell>
                </ng-container>

                <ng-container matColumnDef="business_id">
                  <mat-header-cell *matHeaderCellDef mat-sort-header>Business ID. </mat-header-cell>
                  <mat-cell *matCellDef="let element">{{element.business_id}}</mat-cell>
                </ng-container>

                <ng-container matColumnDef="activity_code">
                  <mat-header-cell *matHeaderCellDef>Activity Code. </mat-header-cell>
                  <mat-cell *matCellDef="let element">{{element.activity_code}}</mat-cell>
                </ng-container>

                <ng-container matColumnDef="plot_number">
                  <mat-header-cell *matHeaderCellDef style="justify-content: center;">Plot No. </mat-header-cell>
                  <mat-cell *matCellDef="let element" style="justify-content: center;">{{element.plot_number}}
                  </mat-cell>
                </ng-container>

                <ng-container matColumnDef="ward_name">
                  <mat-header-cell *matHeaderCellDef style="justify-content: center;">Ward</mat-header-cell>
                  <mat-cell *matCellDef="let element" style="justify-content: center;">{{element.ward_name}}

                    <p *ngIf="element.ward_name ==null">
                      <span style="color:red !important;">please update</span>
                    </p>

                  </mat-cell>
                </ng-container>

                <ng-container matColumnDef="sub_county_name">
                  <mat-header-cell *matHeaderCellDef style="justify-content: center;">Sub County</mat-header-cell>
                  <mat-cell *matCellDef="let element" style="justify-content: center;">{{element.sub_county_name}}
                    <!-- <mat-chip *ngIf="element.sub_county_name ==null" color="warn">One fish</mat-chip> -->
                    <p *ngIf="element.sub_county_name ==null">
                      <span style="color:red !important;">please update</span>
                    </p>

                  </mat-cell>
                </ng-container>


                <ng-container matColumnDef="Actions">
                  <mat-header-cell *matHeaderCellDef>Actions</mat-header-cell>
                  <mat-cell *matCellDef="let row">
                    <button mat-icon-button matTooltip="View Permit." (click)="viewPermit(row)">
                      <mat-icon>visibility</mat-icon>
                    </button>
                    <button mat-icon-button mat-icon-button matTooltip="Edit Permit." (click)="editPermit(row)">
                      <mat-icon>create</mat-icon>
                    </button>
                  </mat-cell>
                </ng-container>


                <ng-container matColumnDef="loading">
                  <mat-footer-cell *matFooterCellDef colspan="6">
                    <ngx-spinner bdColor="rgba(51,51,51,0.8" size="medium" color="#fff" loadingText="Loading..."
                      type="ball-scale-multiple"></ngx-spinner>
                  </mat-footer-cell>
                </ng-container>

                <ng-container matColumnDef="noData">
                  <mat-footer-cell *matFooterCellDef colspan="6">
                    No Data
                  </mat-footer-cell>
                </ng-container>


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

                <mat-footer-row *matFooterRowDef="['loading']" [ngClass]="{'hide': listData!=null}"></mat-footer-row>

                <mat-footer-row *matFooterRowDef="['noData']"
                  [ngClass]="{'hide': !(listData!=null && listData.data.length==0)}">
                </mat-footer-row>

              </table>
              <!-- <mat-paginator [pageSizeOptions]="[5,10,25,100]" [pageSize]="5" showFirstLastButtons></mat-paginator> -->
              <mat-paginator 
                [length]="pageLength "
                [pageSize]="pageSize"
                [pageSizeOptions]="pageSizeOptions">
                </mat-paginator>

<!-- 
              <ul class="na-pills">
                <li class="nav-item" *ngFor="let p of pages; let i=index">
                  <a  class="nav-link" (click)="setPage(i,$event)">{{i}}</a>
                </li>
              </ul> -->
            </div>
          </mat-card>

        </div>

      </div>
    </div>
  </div>

</div>

TS file

export class PermitListComponent implements OnInit {

  page: number;

  pages: Array<number>;

  listData: MatTableDataSource<any>;

  displayedColumns: string[] = ['business_name',
  'business_id', 'activity_code', 'plot_number', 'ward_name', 'sub_county_name', 'Actions'];


  @ViewChild(MatSort, {static: true}) sort: MatSort;

  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;

  searchKey: string;

  selectedPermit: any;

  businessId: number;

  pageEvent: PageEvent;

  //var init declaration
  pageLength = 100;
  pageSize = 10;
  pageSizeOptions: number[] = [5, 10, 25, 100];



  constructor(
    private liquorService: LiquorService,
    private dialog: MatDialog,
    private snackbar: MatSnackBar,
    private spinner: NgxSpinnerService,
    private dataService: DataService) { 
      this.liquorService.listen().subscribe((m: any) => {
        console.log(m);
        this.getAllPermits();
    });
    }



  ngOnInit() {

    this. getAllPermits();

    /** spinner starts on init **/

    this.spinner.show();
    /** spinner starts afer 5 secs**/
    setTimeout(() => {
      this.spinner.hide();

    }, 5000);
  }

  setPage(i, event: any) {
    this.page = i;
    // event.preventDefault;
    this.getAllPermits();

  }

  getAllPermits() {
    this.page = 1;
    this.liquorService.getAllPermits().subscribe(
      res => {
        this.listData = new MatTableDataSource(res.data.results);
        this.listData.sort = this.sort;

        // this.pages = new Array(res.data.total_pages);

        const sortState: Sort = {active: 'id', direction: 'desc'};
        this.sort.active = sortState.active;
        this.sort.direction = sortState.direction;
        this.sort.sortChange.emit(sortState);

        // this.pages = new Array(res.data.total_pages);

        this.pageLength = res.data.total_pages;

        this.listData.paginator = this.paginator;
      },

      error => {
        console.log(error);
      }
    );
  }


  onSearchClear() {
    this.searchKey = '';
    this.applyFilter();
  }

  applyFilter() {
    // console.log(this.listData)
    this.listData.filter = this.searchKey.trim().toLocaleLowerCase();
  }


  onClickAddPermit() {
    // console.log("hello");
    const dialogConfig = new MatDialogConfig();
    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '70%';
    this.dialog.open(AddPermitFormComponent, dialogConfig);

  }

  // closeModal() {
  //   const dialogConfig = new MatDialogConfig();
  //   dialogConfig.disableClose = true;
  //   dialogConfig.autoFocus = true;
  //   dialogConfig.width = '70%';
  //   this.dialog.open(AddPermitFormComponent, dialogConfig);
  // }

  viewPermit(row: any) {
    // this.selectedLicense = row;
    // console.log(this.selectedLicense);
    this.dataService.formData = row;
    this.selectedPermit = row;
    const dialogConfig = new MatDialogConfig();
    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '70%';
    this.dialog.open(EditPermitComponent, dialogConfig);
  }


  editPermit(row: any) {
    // this.selectedLicense = row;
    // console.log(this.selectedLicense);
    this.dataService.formData = row;
    this.selectedPermit = row;
    const dialogConfig = new MatDialogConfig();
    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '70%';
    this.dialog.open(EditPermitFormComponent, dialogConfig);
  }

  onDelete(id: number) {
    this.businessId = id;
    console.log(id);

    if (confirm('Are You Sure to delete ??')) {

      this.liquorService.deleteIssuedPermit(this.businessId).then(
        res => {
          this.getAllPermits();
          const msg = 'Deleted successfully';
          // res.msg.toString()
          this.snackbar.open(msg, '', {
            duration: 5000,
            verticalPosition: 'top'
          });
          // Swal.fire('Success!', 'De  leted!', 'success');
          // this.requestData = res;
          // console.log(this.requestData.status);

        }
      );

    }

  }

Screenshot

enter image description here

Upvotes: 1

Views: 11357

Answers (2)

Philip Mutua
Philip Mutua

Reputation: 6871

I decided not to use mat-paginator to use this html pagination.

HTML

      <ul class="nav nav-pills">
        <li class="nav-item" *ngFor="let p of pages; let i=index">
          <a  class="nav-link" (click)="setPage(i,$event)"  [ngClass]="{'active': i===page}">{{i}}</a>
        </li>
      </ul>

The in the ts file:

Ts file

export class PermitListComponent implements OnInit {

  page = 1;

  pages: Array<number>;

  listData: MatTableDataSource<any>;

  displayedColumns: string[] = ['business_name',
  'business_id', 'activity_code', 'plot_number', 'ward_name', 'sub_county_name', 'Actions'];


  @ViewChild(MatSort, {static: true}) sort: MatSort;

  @ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;

  searchKey: string;

  selectedPermit: any;

  businessId: number;

  pageEvent: PageEvent;

  paginatedResp: any;
      

  constructor(
    private liquorService: LiquorService,
    private dialog: MatDialog,
    private snackbar: MatSnackBar,
    private spinner: NgxSpinnerService,
    private dataService: DataService) { 
      this.liquorService.listen().subscribe((m: any) => {
        console.log(m);
        this.getAllPermits();
    });
    }



  ngOnInit() {

    this. getAllPermits();

    /** spinner starts on init **/

    this.spinner.show();
    /** spinner starts afer 5 secs**/
    setTimeout(() => {
      this.spinner.hide();

    }, 5000);
  }

  setPage(i, event: any) {
    this.page = i;
    event.preventDefault;
    this.getAllPermits();

  }

  getAllPermits() {
    // this.page = 1;
    this.liquorService.getAllPermitList(this.page).subscribe(
      res => {
        this.paginatedResp = res;
        this.listData = new MatTableDataSource(this.paginatedResp.data.results);
        this.listData.sort = this.sort;

        this.pages = new Array(this.paginatedResp.data.total_pages);

        const sortState: Sort = {active: 'id', direction: 'desc'};
        this.sort.active = sortState.active;
        this.sort.direction = sortState.direction;
        this.sort.sortChange.emit(sortState);


        this.listData.paginator = this.paginator;
      },

      error => {
        console.log(error);
      }
    );
  }


  onSearchClear() {
    this.searchKey = '';
    this.applyFilter();
  }

  applyFilter() {
    // console.log(this.listData)
    this.listData.filter = this.searchKey.trim().toLocaleLowerCase();
  }


  onClickAddPermit() {
    // console.log("hello");
    const dialogConfig = new MatDialogConfig();
    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '70%';
    this.dialog.open(AddPermitFormComponent, dialogConfig);

  }

  // closeModal() {
  //   const dialogConfig = new MatDialogConfig();
  //   dialogConfig.disableClose = true;
  //   dialogConfig.autoFocus = true;
  //   dialogConfig.width = '70%';
  //   this.dialog.open(AddPermitFormComponent, dialogConfig);
  // }

  viewPermit(row: any) {
    // this.selectedLicense = row;
    // console.log(this.selectedLicense);
    this.dataService.formData = row;
    this.selectedPermit = row;
    const dialogConfig = new MatDialogConfig();
    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '70%';
    this.dialog.open(EditPermitComponent, dialogConfig);
  }


  editPermit(row: any) {
    // this.selectedLicense = row;
    // console.log(this.selectedLicense);
    this.dataService.formData = row;
    this.selectedPermit = row;
    const dialogConfig = new MatDialogConfig();
    dialogConfig.disableClose = true;
    dialogConfig.autoFocus = true;
    dialogConfig.width = '70%';
    this.dialog.open(EditPermitFormComponent, dialogConfig);
  }

  onDelete(id: number) {
    this.businessId = id;
    console.log(id);

    if (confirm('Are You Sure to delete ??')) {

      this.liquorService.deleteIssuedPermit(this.businessId).then(
        res => {
          this.getAllPermits();
          const msg = 'Deleted successfully';
          // res.msg.toString()
          this.snackbar.open(msg, '', {
            duration: 5000,
            verticalPosition: 'top'
          });
          // Swal.fire('Success!', 'De  leted!', 'success');
          // this.requestData = res;
          // console.log(this.requestData.status);

        }
      );

    }

  }




}

Then Updated the service file:

Service file

  getAllPermitList(id: number) {
    console.log(id)
    return this.http.get<any>(`${environment.apiUrl}/api/business_list/?page=` + id, {
      headers: this.headers
    });
  }

Output

enter image description here

When I click on the page number I get the data from that page.

Upvotes: 1

CodeMonkey
CodeMonkey

Reputation: 26

You can simply use a public variable and fill it with the value from your response.

  //var init declaration
  length = 100;
  pageSize = 10;
  pageSizeOptions: number[] = [5, 10, 25, 100];

Then use it in your template like this:

<mat-paginator 
           [length]="length"
           [pageSize]="pageSize"
           [pageSizeOptions]="pageSizeOptions"
</mat-paginator>

Upvotes: 0

Related Questions