I want to filter my grids having both menu and row filter option. As it is a common scenario, some columns represent a "text-value" field; for example, the category column in Products grid. For this type of columns, I would like to have a "Kendo UI Multi Select" in the menu (which filters based on the value of category), and a simple string filter in the filter row (which basically applies string filtering on the name of category). I wrote the following code to accomplish this, but apparently the grid is got confused to filter based on category' value or category's name.
Here is the template:
<kendo-grid [data]="gridData" [pageSize]="state.take" [skip]="state.skip" [sort]="state.sort" [filter]="state.filter" filterable="menu, row" [sortable]="true" [pageable]="true" (dataStateChange)="dataStateChange($event)" [height]="400"> <kendo-grid-column field="ProductName" title="Product Name"> </kendo-grid-column> <kendo-grid-column field="Category.CategoryName" title="Category"> <ng-template kendoGridFilterMenuTemplate let-column="column" let-filter="filter" let-filterService="filterService"> <kendo-multiselect [data]="categories" textField="CategoryName" valueField="CategoryID" [valuePrimitive]="true" [value]="categoryFilters(filter)" (valueChange)="categoryChange($event, filterService)"> </kendo-multiselect> </ng-template> <ng-template kendoGridCellTemplate let-dataItem> {{dataItem.Category?.CategoryName}} </ng-template> </kendo-grid-column></kendo-grid>and here is part of the .ts file:
01. public filterChange(filter: CompositeFilterDescriptor): void {02. this.state.filter = filter;03. }04. 05. public categoryChange(values: any[], filterService: FilterService): void {06. filterService.filter({07. filters: values.map(value => ({08. field: 'Category.CategoryID',09. operator: 'eq',10. value11. })),12. logic: 'or'13. });14. }15. 16. public categoryFilters(filter: CompositeFilterDescriptor): FilterDescriptor[] {17. return flatten(filter).map(({ value }) => value);18. }19. 20. public dataStateChange(state: DataStateChangeEvent): void {21. this.state = state;22. this.gridData = process(sampleProducts, this.state);23. }24. 25. 26. public state: State = {27. skip: 0,28. take: 6,29. };30. 31.public categories: any[] = distinct(sampleProducts);32. public gridData: GridDataResult = process(sampleProducts, this.state);33. 34. 35.const flatten = filter => {36. const filters = (filter || {}).filters;37. if (filters) {38. return filters.reduce((acc, curr) => acc.concat(curr.filters ? flatten(curr) : [curr]), []);39. }40. return [];41.};42. 43.const distinct = data => data44. .map(x => x.Category)45. .filter((x, idx, xs) => xs.findIndex(y => y.CategoryName === x.CategoryName) === idx);
