I'm new to Angular and I want to sort data in "Active" column. I am sorting all the columns with mat-sort-header (for example: email column) and it is working fine with an exception of isActive column where I am showing mat-icon. I want to sort this column by the value from element.isActive so the column will be sorted by active/non active icons. I'm not sure about how to specify the sorting in this column. This is my mat table: I'm working with Angular and material designs.

<div fxLayout="column" style="margin-top:-2.6vh;">
  <table fxFlex mat-table [dataSource]="users" matSort multiTemplateDataRows class="mat-elevation-z8">

    <!-- Checkbox Column -->
    <ng-container matColumnDef="select">
      //relevant code
    </ng-container>

    <!-- Position Column -->
    <ng-container matColumnDef="firstName">
      //relevant code
    </ng-container>

    <!-- lastName Column -->
    <ng-container matColumnDef="lastName">
      //relevant code
    </ng-container>

    <!-- email Column -->
    <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>

<!-- isActive Column -->
    <ng-container matColumnDef="active">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Active </th>
      <td mat-cell *matCellDef="let element" style=" text-transform:capitalize">

        <mat-icon *ngIf="element.isActive; else elseBlock" color="primary">fiber_manual_record</mat-icon>
        <ng-template #elseBlock><mat-icon color="warm">fiber_manual_record</mat-icon></ng-template>
      </td>
    </ng-container>

    <!-- Actions Column -->
    <ng-container matColumnDef="actionsColumn">
      //relevant code
    </ng-container>


    <!-- Expanded Content -->
    <ng-container matColumnDef="expandedDetail">
      //relevant code
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>

    <tr mat-row *matRowDef="let element; columns: displayedColumns;"
        class="example-element-row"
        [class.example-expanded-row]="expandedElement === element"
        (click)="expandedElement = expandedElement === element ? null : element"></tr>
    <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>

  </table>
  <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>

The TS side:

    import { MatSort, MatTableDataSource } from '@angular/material';
    @Component({
      selector: 'users-list',
      animations: [
        trigger('detailExpand', [
          state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })),
          state('expanded', style({ height: '*' })),
          transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
        ]),
      ],

    })
    export class UsersListComponent implements OnInit, OnDestroy {
      @ViewChild(MatSort) sort: MatSort;
      @ViewChild(MatPaginator) paginator: MatPaginator;

      users: MatTableDataSource<PimUser>;
      selection = new SelectionModel<PimUser>(true, []);
      displayedColumns = ['select', 'firstName', 'lastName', 'email', 'active', 'actionsColumn'];
      isExpansionDetailRow = (i: number, row: Object) => row.hasOwnProperty('detailRow');
      expandedElement: any;
    }
ngOnInit() {
   this.users.sort = this.sort; 
}

This is how my table looks like : enter image description here

Any ideas on how can I do it? Thank you.

1 Answers

0
Prashant Pimpale On

You need to assign this.sort to the sort property of MatTableDataSource, so in ngOnInit() add below line

sort property:

An instance of the MatSort directive used by the table to control its sorting. Sort changes emitted by the MatSort will trigger an update to the table's rendered data.

ngOnInit() {
   ........
   ........
   this.data.sort = this.sort;  // assign this.sort to the property of DataSource
}

WORKING_DEMO