Home > Software design >  Creating reusable Angular Material table with pagination, filtering and sorting
Creating reusable Angular Material table with pagination, filtering and sorting

Time:01-29

I'm working with Angular Material in my project. I'll use many tables in my project and because of the high complexity of this project, I want to use a reusable table in order to avoid code duplication. I tried to create a reusable table without filtering and pagination:

table.component.html

<table mat-table [dataSource]="dataSource" >
    <ng-container
      *ngFor="let disCol of tableColumns let colIndex = index;"
      matColumnDef="{{disCol.columnDef}}"
    >
      <th mat-header-cell *matHeaderCellDef>
        {{ disCol.header }}
      </th>
  
      <td mat-cell *matCellDef="let element">
        <span *ngIf="!disCol.isLink; else link">
          {{ disCol.cell(element) }}
        </span>
  
        <ng-template #link>
          <a [routerLink]="[disCol.url]">
            {{ disCol.cell(element) }}
          </a>
        </ng-template>
      </td>
    </ng-container>
  
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>

table.component.ts

export class TableComponent implements OnInit {
  @Input()
  tableColumns: Array<TableColumn> = [];

  @Input()
  tableData: Array<any> = [];

  displayedColumns: Array<string> = [];
  dataSource: MatTableDataSource<any> = new MatTableDataSource();

  constructor() {}

  ngOnInit(): void {
    this.displayedColumns = this.tableColumns.map((c) => c.columnDef);
    this.dataSource = new MatTableDataSource(this.tableData);
  }
}

TableColumn.ts

export interface TableColumn {
    columnDef: string;
    header: string;
    cell: Function;
    isLink?: boolean;
    url?: string;
}

I want to add server-side pagination, filtering and sorting. My API (ASP.NET Core API based on EF Core) can take two parameters of pageNumber and pageSize to provide desired data.

[HttpGet]
        public async Task<IActionResult> GetEquipmentFilterCategory(int pageNumber, int pageCapacity, string categoryName)
        {
            int skip = (pageNumber - 1) * pageCapacity;

            var list = await _sqlServerContext.Equipments.Where(x => x.EquipmentCategory!.CategoryName == categoryName)
                .OrderByDescending(x => x.EquipmentId)
                .Skip(skip).Take(pageCapacity)
                .Include(x => x.CostCenter)
                .Include(x => x.EquipmentCategory)
                .Include(x => x.equipmentType)
                .ToListAsync();

            if (list.Count > 0)
            {
                return Ok(list);
            }
            return NoContent();
        }

        [HttpGet]
        public async Task<IActionResult> GetTotalEquipmentCount()
        {
            var totalCount = await _sqlServerContext.Equipments.CountAsync();
            return Ok(totalCount);
        }

How can I add server-side pagination, filtering and soring to this reusable MatTable?

CodePudding user response:

What you're looking for is already in Angular Material Table's examples as a Wrapper Table (https://material.angular.io/components/table/examples#table-wrapped). You can take this as a starting point for implementing this the way you want. All you need to do now is to add ContentChild for MatPaginator and inject MatSort in constructor.

  • Related