はじめに
Angular Material のTableコンポーネントでSortするときに、単純な数値や文字列の順序ではなく、独自のステータス(松竹梅など)でSortする方法をまとめます。
※ Angular MaterialはGoogleが提唱しているMaterial Designに準拠したAngular用のUIコンポーネント集です。
基本となるテーブル
まず、基本的なSortに対応したテーブルを作成します。
- sample-table.component.html
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
<!-- no Column -->
<ng-container matColumnDef="no">
<th mat-header-cell *matHeaderCellDef mat-sort-header> No. </th>
<td mat-cell *matCellDef="let element"> {{element.no}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- course Column -->
<ng-container matColumnDef="course">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Course </th>
<td mat-cell *matCellDef="let element"> {{element.course}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
- sample-table.component.ts
export interface Reservation {
no: number;
name: string;
course: string;
}
const SAMPLE_DATA: Reservation[] = [
{no: 0, name: "佐藤", course: "松"},
{no: 1, name: "鈴木", course: "松"},
{no: 2, name: "高橋", course: "梅"},
{no: 3, name: "田中", course: "松"},
{no: 4, name: "伊藤", course: "竹"},
{no: 5, name: "渡辺", course: "松"},
{no: 6, name: "山本", course: "梅"},
{no: 7, name: "中村", course: "竹"},
{no: 8, name: "小林", course: "竹"},
{no: 9, name: "加藤", course: "梅"},
{no: 10, name: "吉田", course: "松"},
{no: 11, name: "山田", course: "竹"},
{no: 12, name: "佐々木", course: "松"},
];
@Component({
selector: 'sample-table',
styleUrls: ['sample-table.component.css'],
templateUrl: 'sample-table.component.html',
})
export class SampleTableComponent implements OnInit {
displayedColumns: string[] = ['no', 'name', 'course'];
dataSource = new MatTableDataSource(SAMPLE_DATA);
@ViewChild(MatSort, {static: true}) sort: MatSort;
ngOnInit() {
this.dataSource.sort = this.sort;
}
}
- sample-table.component.css
table {
width: 100%;
}
th.mat-sort-header-sorted {
color: black;
}
ちなみに、この段階で、courseで昇順にすると、松→梅→竹になります。
これを松→竹→梅になるように対応します。
Sort順序のカスタマイズ
Sort順序のカスタマイズにはMatTableDataSource
のsortingDataAccessor
を利用します。
sortingDataAccessor
の型定義は下記の通りです。
(data: T, sortHeaderId: string) => string | number
dataはSAMPLE_DATAの1行分のデータが入ります。そのため、この関数は行数分コールされます。
sortHeaderIdはSort対象のidが入ります。(courseカラムのSortを実行した場合は"course")
Sort順序をカスタマイズするには、下記のようにsortingDataAccessor
へ関数を代入します。
- sample-table.component.ts
ngOnInit() {
this.dataSource.sort = this.sort;
this.dataSource.sortingDataAccessor = (item, property) => {
if (property == "course") {
switch (item.course) {
case "松":
return 0;
case "竹":
return 1;
case "梅":
return 2;
default:
return 3;
}
}
return (item as any)[property];
};
}
まず、if (property == "course")
でcourseカラムのSortのときだけ動作するようにします。それ以外はreturn (item as any)[property];
でデフォルト動作になるようにしています。
if文の中では松竹梅に合わせてnumber型を返します。これにより、任意の値のSort順序を制御できます。