1
votes

I'm wondering how can I group the filter values of a column by a property field of a collection.

The column data:

{ 
  users: [
    {id: 1, isExternal: true, name: "John" }, 
    {id: 2, isExternal: false, name: "George"},
    {id: 3, isExternal: true, name: "Bob"}
  ]
}

The external users are formatted by a valueGetter function:

columnDefs: [
  {
    enableRowGroup: true,
    field: "users",
    headerName: "Users",
    minWidth: 150,
    filter: "agSetColumnFilter",
    valueGetter: (params: any) => {
      return (params.data.users || []).map((user: User) =>
        user.isExternal ? `${user.name} (EXT)` : user.name
      );
    }
  }
];

I ended up having the column filter with many checkboxes of each value.

Would it be possible to group the filter items into 1 checkbox?

For example: a checkbox filter named "External", where it would filter in all external users and when unchecked, it would display all users.

1
do you have the id of the user on the params argument of the valueGetter function?profanis
Yes, all the fields I can retrieve from params.data.users.Marco Nascimento

1 Answers

2
votes

You can build a custom filter to achieve that.

How to build a custom filter

Accordingly to this doc, you need to build two components:

  • the actual filter component, who checks if the column data have the correct value
  • a "floating filter", in the case that you want to use this filter behind the header of the column

The floating filter calls the logic in the "main" filter and updates the view in the table.

For the main filter, the code could be like this:

     @Component(  selector: 'app-boolean-filter',
                         template: '
<div class="ag-filter">
   <select [(value)]="currentFilterValue" (change)="filterChange($event.target.value)">
      <option value="">all values</option>
      <option value="true">yes</option>
      <option value="false">no</option>
   </select>
</div>',
      style: '.ag-filter {  
        width: 100%;
        select {
            width: 100%;
            min-height: 24px;
            border-radius: 3px;
            padding-left: 6px;
            border-width: 1px;
            border-style: solid;
            border-color: #babfc7;
        }
    }')
    
    export class BooleanFilterComponent implements IFilterAngularComp {
      currentFilterValue: any;
    
      private params: IFilterParams;
      private valueGetter: (rowNode: RowNode) => any;
    
      agInit(params: IFilterParams): void {
        this.params = params;
        this.currentFilterValue = null;
        this.valueGetter = params.valueGetter;
      }
    
      isFilterActive(): boolean {
        return this.currentFilterValue !== null;
      }
    
      doesFilterPass(params: IDoesFilterPassParams): boolean {
        const valueGetter: any = this.valueGetter;
        const value: any = valueGetter(params);
    
        if (this.isFilterActive()) {
          return value === JSON.parse(this.currentFilterValue);
        }
      }
    
      getModel(): any {
        return this.isFilterActive() ? this.currentFilterValue : null;
      }
    
      setModel(model: any): void {
        this.filterChange(model);
      }
    
      afterGuiAttached(params: IAfterGuiAttachedParams): void {
      }
    
      takeValueFromFloatingFilter(value: any): void {
        this.filterChange(value);
      }
    
      filterChange(newValue: any): void {
        this.currentFilterValue = newValue === '' ? null : newValue;
        this.params.filterChangedCallback();
      }
    }

The doesFilterPass method is where the magic hapens: the valueGetter(params), gets the value from the data field that you configure in the grid column and checks if it passes the filter, hidding or showing it in the table.