Reputation: 347
I use angular 9 with Nebular v6.1.0 I have a list of elements that is displayed in the interface. For this I use the nebular TreeGridComponent. Every property of my object can be filtered and sorted without problems as long as it is a basic data type like string or number. However, my object also contains complex data types of the type of another object. It does not seem to be possible to filter on the properties of this object, although they can be displayed without problems. I hope it is understandable what I mean by this. Here is a small example:
import { Component } from '@angular/core';
import { NbGetters, NbTreeGridDataSource, NbTreeGridDataSourceBuilder } from '@nebular/theme';
interface FSEntry {
name: string;
myObject: MyObject;
}
interface MyObject {
myObjectName: string;
}
@Component({
template: `
<nb-card>
<nb-card-body>
<table [nbTreeGrid]="source" nbSort (sort)="changeSort($event)">
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="allColumns"></tr>
<tr nbTreeGridRow *nbTreeGridRowDef="let row; columns: allColumns"></tr>
<!-- this row is sortable -->
<ng-container nbTreeGridColumnDef="name">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef [nbSortHeader]="getDirection('name')">Name</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
row.data.name
</td>
</ng-container>
<!-- this row is NOT sortable -->
<ng-container nbTreeGridColumnDef="myObjectName">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef [nbSortHeader]="getDirection('myObjectName')">MyObjectName</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
row.data.myObject.myObjectName
</td>
</ng-container>
</table>
</nb-card-body>
</nb-card>
`,
styleUrls: ['./tree-grid-shared.scss'],
})
export class TreeGridComponent {
defaultColumns = [ 'name', 'myObjectName' ];
allColumns = [ ...this.defaultColumns ];
source: NbTreeGridDataSource<FSEntry>;
constructor(dataSourceBuilder: NbTreeGridDataSourceBuilder<FSEntry>) {
const getters: NbGetters<FSEntry, FSEntry> = {
dataGetter: (node: FSEntry) => node,
childrenGetter: (node: FSEntry) => node.childEntries || undefined,
expandedGetter: (node: FSEntry) => !!node.expanded,
};
this.source = dataSourceBuilder.create(this.data, getters);
}
getDirection(column: string): NbSortDirection {
if (column === this.sortColumn) {
return this.sortDirection;
}
return NbSortDirection.NONE;
}
changeSort(sortRequest: NbSortRequest): void {
this.dataSource.sort(sortRequest);
this.sortColumn = sortRequest.column;
this.sortDirection = sortRequest.direction;
}
private data: FSEntry[] = [
{
name: 'name 1',
myObject: {
myObjectName: 'myObjectName 1'
}
},
{
name: 'name 2',
myObject: {
myObjectName: 'myObjectName 2'
}
}
];
}
With this Code it is possible to sort the name
-Row Ascending or Descending, but not the myObjectName
-Row.
Is there any way to fix that without moving the properties from MyObject
to FSEntry
?
Upvotes: 1
Views: 1202
Reputation: 21
Maybe this will help you? Create a custom class which extends NbTreeGridFilterService
import { NbTreeGridFilterService } from '@nebular/theme';
export class CustomTreeGridFilterService<T> extends NbTreeGridFilterService<T> {
protected filterPredicate(data: T, searchQuery: string): boolean {
const preparedQuery = searchQuery.trim().toLocaleLowerCase();
for (const val of Object.values(data)) {
const prepVal = this.prepValue(val);
const preparedVal = `${prepVal}`.trim().toLocaleLowerCase();
if (preparedVal.includes(preparedQuery)) {
return true;
}
}
return false;
}
prepValue(value): string[] {
const x = [];
const isObject = typeof value === 'object' && value !== null;
if (!isObject) {
x.push(value);
} else {
for (const val of Object.values(value)) {
x.push(this.prepValue(val));
}
}
return x;
}
}
and then in your component use it like so
constructor() {
const filterService = new CustomTreeGridFilterService<Client>();
const sortService = new NbTreeGridSortService<Client>();
const treeGridService = new NbTreeGridService<Client>();
const treeGridDataService = new NbTreeGridDataService<Client>();
const dataSourceBuilder = new NbTreeGridDataSourceBuilder<Client>(filterService, sortService, treeGridService, treeGridDataService);}
For sorting you can do something similar.
Upvotes: 2