coreui / coreui-angular

CoreUI Components Library for Angular https://coreui.io/angular/docs/
https://coreui.io/angular/
MIT License
248 stars 146 forks source link

Smart Table Component FilterTable not working with columns contains object #170

Closed Stewioie closed 1 year ago

Stewioie commented 1 year ago

Operating System Windows 10 21H2 Browser Chrome v110.0.5481.178

<c-smart-table #smartTable="cSmartTable" activePage="1" [columns]="liftColumns"
  [columnFilter]="false" [columnSorter]="true" header clickableRows [itemsPerPage]="10"
  [items]="this.lifts" itemsPerPageLabel="{{ 'itemsPerPage' | translate}}"
  noItemsLabel="{{ 'noItems' | translate}}" [itemsPerPageSelect]="true" pagination
  tableFilterLabel="" tableFilterPlaceholder="{{ 'lifts.search' | translate}}"
  [tableProps]="{ hover: true, striped: true, responsive: true }" [tableFilter]="true">
  <ng-template cTemplateId="tableData" let-columnName="columnName" let-item="item"
      let-tdContent="tdContent">
      <td [cTableActive]="smartTable.tableDataCellProps(item, columnName)?.['active']"
          [cTableColor]="smartTable.tableDataCellProps(item, columnName)?.color"
          [cAlign]="smartTable.tableDataCellProps(item, columnName)?.align"
          [ngClass]="smartTable.tableDataCellClasses(item, columnName)">
          <ng-container [ngSwitch]="columnName">
              <ng-container *ngSwitchCase="'building'">
                  {{item[columnName] !== undefined ? item[columnName].name : "-"}}
              </ng-container>
              <ng-container *ngSwitchDefault>
                  {{tdContent}}
              </ng-container>
          </ng-container>
      </td>
  </ng-template>
</c-smart-table>

For column "building" the table filter wont show any results... for the rest of the columns its ok

xidedix commented 1 year ago

@Stewioie the easy way is to flatten your items array, sth like :

  liftsFlatten = lifts.map((item) => {
    return { ...item, buildingName: item.building.name };
  });

and update your liftColumns accordingly

xidedix commented 1 year ago

@Stewioie The other option is to use columnFilter="{external: true}" and handle (columnFilterValueChange) with your custom filter function (for all columns). One drawback of this approach - you'll also need an external columnSorter to sort this specific column (and rest of the columns).

xidedix commented 1 year ago

@Stewioie starting from v4.3.16 (not documented yet) you can also pass custom functions for column filter and sorter:

liftColumns = [
...
  {
    key: 'building',
    filter: (item: ILitf, value: string) => item.building?.name?.toLowerCase().startsWith(value.toLowerCase().trim()),
    sorter: (itemA: ILitf, itemB: ILitf) => {
      const a = itemA.building?.name?.toLowerCase() ?? ''
      const b = itemB.building?.name?.toLowerCase() ?? ''
      return a > b ? 1 : b > a ? -1 : 0;
    }
  },
...
];
Stewioie commented 1 year ago

@Stewioie the easy way is to flatten your items array, sth like :

  liftsFlatten = lifts.map((item) => {
    return { ...item, buildingName: item.building.name };
  });

and update your liftColumns accordingly

Thanks it works