rossco
rossco

Reputation: 625

How to use conditional formatting of Angular Material Table values

I have a mat-table that is working fine, all values display exactly in the format returned by the DB

  <mat-table #table [dataSource]="queryResults" matSort >

    <ng-container *ngFor="let column of displayedColumns" matColumnDef="{{column.name}}">
      <mat-header-cell *matHeaderCellDef mat-sort-header>{{ column.viewValue }}</mat-header-cell>
      <mat-cell *matCellDef="let item">{{item[column.name]}}</mat-cell>
    </ng-container>

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

  </mat-table>

The data structure of each item looks something like this. There are over 300 columns returned from the DB which the user can select from, so I don't want to hard code the table definition, instead I have a JSON structure that defines the columns and their values

 export interface SearchFields {
    name: string;
    viewValue: string;
    fieldType?: string;
    dispFormat?: string;
  }

Now I want to conditionaly format some values using dispFormat. Possible values of dispFormat are '' (left blank) currency or number I'm not sure how to implement a currency or number pipe, or have no formatting based on the column definition. I have tried adding *ngIf which is not correct


<mat-table #table [dataSource]="queryResults" matSort >

    <ng-container *ngFor="let column of displayedColumns" matColumnDef="{{column.name}}">
      <mat-header-cell *matHeaderCellDef mat-sort-header>{{ column.viewValue }}</mat-header-cell>
      <ng-template #currValue *ngIf="column.dispFormat=='currency'" ><mat-cell *matCellDef="let item" >{{item[column.name] | currency:'USD':true:'2.2-4'}}</mat-cell></ng-template>
      <ng-template #noFormatValue *ngIf="column.dispFormat==''" > <mat-cell *matCellDef="let item" >{{item[column.name]}}</mat-cell></ng-template>
    </ng-container>

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

  </mat-table>

But this gives errors due to mixing *ngIf and *matCellDef

ERROR TypeError: Cannot read property 'template' of undefined

How can I format the values based on a condition?

EDIT - As requested, adding sample data
Sample dataSource is:

[{name: 'Company A',
accountspayable: 172286000,
accumulatedamortization: null,
beta: 0.5718,
bookvalue: 15.128,
buy: 0},
{name: 'Company B',
accountspayable: 112676000,
accumulatedamortization: 1689965,
beta: 0.5,
bookvalue: 27.5,
buy: 1},
{name: 'Company C',
accountspayable: 126546000,
accumulatedamortization: 1889965,
beta: 0.168,
bookvalue: 10,
buy: 5}
]

Column definitions are:

[
{ name: 'name', viewValue: 'Name',dispFormat: '' },
{ name: 'accountspayable', viewValue: 'Accounts Payable', dispFormat: 'currency' },
{ name: 'accumulatedamortization', viewValue: 'Accumulated Amortization', dispFormat: 'currency' },
{ name: 'beta', viewValue: 'Beta', dispFormat: 'number' },
{ name: 'bookvalue', viewValue: 'Book Value', dispFormat: 'currency' },
{ name: 'buy', viewValue: 'Buy', dispFormat: 'number' }
]

Upvotes: 1

Views: 4688

Answers (2)

rossco
rossco

Reputation: 625

I've found the answer, it's simply to put the ngIf inside the mat-cell

  <mat-table #table [dataSource]="queryResults" matSort >

    <ng-container *ngFor="let column of displayedColumns" matColumnDef="{{column.name}}">
      <mat-header-cell *matHeaderCellDef mat-sort-header>{{ column.viewValue }}</mat-header-cell>
      <mat-cell *matCellDef="let item">
        <div *ngIf="column.dispFormat=='currency'">
          {{item[column.name] | currency:'USD':true:'2.0-4'}}
        </div>
        <div *ngIf="column.dispFormat=='number'">
          {{item[column.name] | number : '2.0-4'}}
        </div>
        <div *ngIf="column.dispFormat==''">
          {{item[column.name]}}
        </div>
      </mat-cell>
    </ng-container>

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

  </mat-table>

Upvotes: 2

vsnikhilvs
vsnikhilvs

Reputation: 576

You might want to try by not changing the mat table syntax:

      <mat-header-cell *matHeaderCellDef mat-sort-header>{{ column.viewValue }}</mat-header-cell>
      <ng-template #currValue *ngIf="column.dispFormat=='currency'" ><mat-cell *matCellDef="let item" >{{item[column.name] | currency:'USD':true:'2.2-4'}}</mat-cell></ng-template>
      <ng-template #noFormatValue *ngIf="column.dispFormat==''" > <mat-cell *matCellDef="let item" >{{item[column.name]}}</mat-cell></ng-template>
    </ng-container>```

could be changed to

```<ng-container *ngFor="let column of displayedColumns" matColumnDef="{{column.name}}">
      <mat-header-cell *matHeaderCellDef mat-sort-header>{{ column.viewValue }}</mat-header-cell>
      <mat-cell *matCellDef="let item" >
        <span *ngIf="column.dispFormat=='currency'">{{item[column.name] | currency:'USD':true:'2.2-4'}}</span>
        <span *ngIf="column.dispFormat==''">{{item[column.name]}}</span>
      </mat-cell>
   </ng-container>

Upvotes: 0

Related Questions