What is the proper way to sort a mat-table which has one column that displays a description rather than the code of a mat-select. Consider the following code example that is an editable mat-table which displays a description of the selected item from the mat-select column in edit mode, when not in edit mode. That means when the grid isn't in edit mode, I call a function to give me the description to display.
In static mode:
<div *ngIf="col.key == 'MGA_ServiceDescription'">
<span >
{{ getServiceDescription(element[col.key]) }}
</span>
</div>
In Edit mode:
mat-form-field *ngSwitchCase="'listServiceDescriptions'" >
<mat-select [(value)]="element[col.key]">
<mat-option *ngFor="let c of filteredServices" [value]="c.SDE_CODE"
{{ c.SDE_DESCRIPTION}}
</mat-option>
</mat-select>
/mat-form-field>
CodePudding user response:
The sortingDataAccessor
takes in the current row and the sort attribute. As you're working on the "occupation", property = occupation, items will be USER_DATA
sortingDataAccessor
applied for all columns so we need to check if it's the column we're interested in. That's why we need a switch/case.
In the 'occupation' column, you have a map occupationsList
which maps X => A, Y => B, Z => C... We want that instead of sorting by X/Y/Z, it should sort by A/B/C => return A/B/C instead, that's why I return description (the mapped value)
this.dataSource = new MatTableDataSource(USER_DATA);
this.dataSource.sortingDataAccessor = (item, property) => {
switch(property) {
case 'occupation': occupationsList.find(o => o.name === item.occupation).description;
default: return item[property];
}
};
this.dataSource.sort = this.sort;
CodePudding user response:
The "best way" when we have an array and one property really is a "select" is add to the array the "description"
Imagine some like
ngOnInit() {
this.dataSource = new MatTableDataSource(
USER_DATA.map((code: any) => {
const serviceDescription = this.serviceDescriptions.find(
(desc: any) => desc.SDE_CODE === code.MGA_ServiceDescription
);
return {
...code,
description: serviceDescription? serviceDescription.SDE_DESCRIPTION: '',
};
})
);
}
Well, ther're some problems. The first is change the "sortHeader", we wnat tha t, when the column was 'MGA_ServiceDescription' sort by the new property, so:
<th
mat-header-cell
*matHeaderCellDef
[mat-sort-header]="col.key=='MGA_ServiceDescription'?'description':col.key"
[disabled]="col.key == 'isEdit'"
>
The another problem is how "edit" the element. If we use a mat-select we can choose that the value of the options was the "SDE_CODE" or the own serviceDescription.
I'm going to select the whole object. But for this we need a compareWith
function
serviceCompareWith=(a:any, MGA_ServiceDescription:any)=>
a.SDE_CODE==MGA_ServiceDescription
And, when change change the two properties, the "MGA_ServiceDescription" and the "description"
change(value:any,element:any)
{
element.MGA_ServiceDescription=value.SDE_CODE;
element.description=value.SDE_DESCRIPTION
}
Now our "mat-select" becomes like
<mat-select [compareWith]="serviceCompareWith"
[value]="element.MGA_ServiceDescription"
(selectionChange)="change($event.value,element)">
<mat-option *ngFor="let service of serviceDescriptions" [value]="service">
{{service.SDE_DESCRIPTION}}
</mat-option>
</mat-select>