Live example
Enabling In-line Filters
To enable the In-line Filters, you must provide an input property named allowRowFiltering
at grid scope.
in-line-filters.component.html
Copy <dike-grid id="grid-filter-types" height="600px" #grid="dkgGrid"
[allowRowFiltering]="gridProperties.allowRowFilter">
</dike-grid>
Open the Floating Configuration Panel and click on the Row Filter checkbox of the Filtering group.
You do not have to define every column as filterable to enable the In-line filters.
As you can see, the DikeGrid shows a textbox for every defined column. Thus, In-line filters are the quickest and easiest way to enable filtering.
When you enable the In-line Filters, the DikeGrid registers them automatically, appending the suffix row-filter to the column id.
When you hide In-line Filters, the DikeGrid removes them automatically, as well.
Open the dev console to see the registerFilterableChange
and deregisterFilterableChange
events output.
Customizing the In-line Filters row
You can change the row's height where the DikeGrid shows the In-line Filters.
In-line Filters conditions
By definition, In-line Filters only have one filter condition . The following table shows the filter type and its corresponding default condition:
Be aware that Binary Filters become Text Filters.
Customizing conditions
You can change the condition of the in-line Filters in two ways: by providing an Injection Token or for a specific grid instance.
Customization by providing an Injection Token
To change the default condition, you must provide the corresponding custom instance to the following Injection Tokens:
Let us define a condition for Text
In-line Filters.
Copy @ NgModule ({
providers : [
{
provide : CUSTOM_ROW_TEXT_FILTER_CONDITIONS ,
useFactory : () : CustomRowTextCaseFilterCondition < Employee > =>
new CustomRowTextCaseFilterCondition < Employee >()
.addExistingCondition ( ConditionType . ENDS_WITH )
}
]
})
export class FilteringModule { }
With the previous code snippet, we have changed the default condition to be Ends With for Text
In-line Filters.
If you add more than one condition to the custom instance, the DikeGrid will take only the first one.
Customization at the grid level
When you provide an Injection Token, you are changing conditions for all DikeGrid instances that live under the place you give the Injection Token.
Sometimes, you want to be specific for a particular DikeGrid instance. Then, to change conditions at the grid scope, you must provide the corresponding custom instance through an input property named gridCustomFilterConditions
.
Let us provide custom conditions for Date
and Numeric
types.
in-line-filters.component.html in-line-filters.component.ts
Copy <dike-grid id="grid-filter-types" height="600px" #grid="dkgGrid"
[gridCustomFilterConditions]="gridCustomConditions">
</dike-grid>
Copy ngOnInit (): void {
//...
// Defining filters at DikeGrid instance level:
this .gridCustomConditions = {
customRowDateFilterConditions : new CustomRowDateFilterCondition < Employee >()
.addExistingCondition ( ConditionType . GREATER_THAN ) ,
customRowNumericFilterConditions : new CustomRowNumericFilterCondition < Employee >()
.addCondition ({
text : 'Custom Row Numeric' ,
value : 'grid-customRowNumericMultipleOf' ,
eval: (entry: Employee, dataColumnDef: DikeDataColumnDef<Employee, number>, values?: DikeNumericFilter): boolean =>
dataColumnDef.getValue(entry) % values.value1 === 0
})
};
}
We have changed the Date
condition to be Greater Than and the Numeric
condition to be grid-customRowNumericMultipleOf .
For Date
types, we took an existing condition, and for Numeric
types, we defined a new custom condition.
Summary
In-line Filters are the quickest and easiest way to enable filtering. Every filter type has a default condition attached, but you can change it by providing a custom condition definition.
Complete code for this section.
in-line-filters.component.html in-line-filters.component.ts filtering.module.ts
Copy <div class="mt-2 flex flex-row flex-wrap items-center justify-around">
<button mat-raised-button
class="flex-none w-56 my-2"
color="primary"
(click)="onGetFilterables()">Filterables
</button>
<button mat-raised-button
class="flex-none w-56 my-2"
color="primary"
(click)="onGetFilteredRows()">Filtered rows
</button>
<button mat-raised-button
class="flex-none w-56 my-2"
color="primary"
(click)="onClearFilter()">Clear filter
</button>
</div>
<dike-grid id="grid-filter-types" height="600px" #grid="dkgGrid"
[displayRowId]="gridProperties.displayRowId"
[gridElevation]="gridProperties.matElevation"
[gridElevationValue]="gridProperties.elevationValue"
[striped]="gridProperties.stripeRows"
[verticalRowLines]="gridProperties.verticalRowLines"
[allowRowFiltering]="gridProperties.allowRowFilter"
[allowSorting]="gridProperties.allowSorting"
[allowPagination]="gridProperties.allowPagination"
(registerFilterableChange)="onRegisterChange($event)"
(deregisterFilterableChange)="onDeregisterChange($event)"
(filterChange)="onFilterChange($event)"
[gridCustomFilterConditions]="gridCustomConditions"
[datasource]="dkgDataSource">
<dike-grid-column
fieldName="employeeId"
headerText="Employee Id"
dataType="Text"
width="350"
order="1"
sortable>
</dike-grid-column>
<dike-grid-column
fieldName="completeNameGroup"
headerText="Complete Name"
order="2">
<dike-grid-column
fieldName="firstName"
headerText="Name"
dataType="Text"
width="150"
sortable>
</dike-grid-column>
<dike-grid-column
fieldName="lastName"
headerText="Surname"
dataType="Text"
width="150"
sortable>
</dike-grid-column>
</dike-grid-column>
<dike-grid-column
fieldName="gender"
headerText="Gender"
dataType="Binary"
width="110"
order="3"
sortable>
</dike-grid-column>
<dike-grid-column
fieldName="age"
headerText="Age"
dataType="Numeric"
contentAlign="center"
width="100"
sortable>
</dike-grid-column>
<dike-grid-column
fieldName="email"
headerText="Email"
dataType="Text"
width="300"
sortable>
</dike-grid-column>
<dike-grid-column
fieldName="hireDate"
headerText="Hire Date"
dataType="Date"
sortable>
</dike-grid-column>
</dike-grid>
Copy import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { Subscription } from 'rxjs' ;
import { DikeGridComponent , DikeGridDataSourceInput , DikeFilterable , DikeGridCustomFilterConditions ,
CustomRowDateFilterCondition , DikeDataColumnDef , CustomRowNumericFilterCondition ,
DikeNumericFilter , ConditionType
} from '@dikesoft/angular-data-grid' ;
import { DikeGridProperties } from 'app/core/config/dike-grid.properties' ;
import { Employee } from 'app/mock-api/common/employees/data.model' ;
import { SampleData } from 'app/services/sample-data.service' ;
import { DikeGridConfig } from 'app/services/dike-grid.config.service' ;
@ Component ({
selector : 'in-line-filters' ,
templateUrl : './in-line-filters.component.html' ,
styleUrls : [ './in-line-filters.component.scss' ] ,
encapsulation : ViewEncapsulation .None ,
changeDetection : ChangeDetectionStrategy .OnPush
})
export class InLineFiltersComponent implements OnInit , OnDestroy {
// Retrieve the DikeGridComponent<T> instance from the view:
@ ViewChild ( 'grid' ) dikeGrid : DikeGridComponent < Employee >;
dkgDataSource : DikeGridDataSourceInput < Employee >;
gridProperties : DikeGridProperties ;
gridCustomConditions : DikeGridCustomFilterConditions < Employee >;
private changeGridPropertiesSubscription : Subscription = Subscription . EMPTY ;
constructor (
private cdr : ChangeDetectorRef ,
private gridConfig : DikeGridConfig ,
private sampleData : SampleData ) { }
ngOnInit () : void {
// Get 1000 entries from the REST API:
this .dkgDataSource = this . sampleData .getEmployees ( 1000 );
// Listening to any config property change:
this .setChangeGridPropertiesSubscription ();
// Defining filters at DikeGrid instance level:
this .gridCustomConditions = {
customRowDateFilterConditions : new CustomRowDateFilterCondition < Employee >()
.addExistingCondition ( ConditionType . GREATER_THAN ) ,
customRowNumericFilterConditions : new CustomRowNumericFilterCondition < Employee >()
.addCondition ({
text : 'Custom Row Numeric' ,
value : 'grid-customRowNumericMultipleOf' ,
eval: (entry: Employee, dataColumnDef: DikeDataColumnDef<Employee, number>, values?: DikeNumericFilter): boolean =>
dataColumnDef.getValue(entry) % values.value1 === 0
})
};
}
ngOnDestroy () : void {
this . changeGridPropertiesSubscription .unsubscribe ();
}
onGetFilterables () : void {
console .log ( 'Filterables: ' , this . dikeGrid . filter .filterables);
}
onGetFilteredRows () : void {
console .log ( 'Filtered rows: ' , this . dikeGrid . filter .getFilteredRows ());
}
onClearFilter () : void {
this . dikeGrid . filter .clearFilter ();
}
onRegisterChange (filterable : DikeFilterable < Employee >) : void {
console .log ( 'Register change: ' , filterable);
}
onDeregisterChange (filterable : DikeFilterable < Employee >) : void {
console .log ( 'Deregister change: ' , filterable);
}
onFilterChange (filterable : DikeFilterable < Employee >) : void {
console .log ( 'Filter change: ' , filterable);
}
private setChangeGridPropertiesSubscription () : void {
this . changeGridPropertiesSubscription .unsubscribe ();
this .changeGridPropertiesSubscription = this . gridConfig . configChange .subscribe ((props : DikeGridProperties ) => {
this .gridProperties = props;
this . cdr .markForCheck ();
});
}
}
Copy import { NgModule } from '@angular/core' ;
import { CommonModule } from '@angular/common' ;
import { RouterModule } from '@angular/router' ;
import { DikeDataGridModule , NUMERIC_FILTER_DEBOUNCE_TIME ,
CUSTOM_ROW_TEXT_FILTER_CONDITIONS , CustomRowTextCaseFilterCondition , ConditionType ,
CUSTOM_TEXT_FILTER_CONDITIONS , CustomTextCaseFilterCondition ,
DikeDataColumnDef , DikeTextFilter } from '@dikesoft/angular-data-grid' ;
import { SharedModule } from 'app/shared/shared.module' ;
import { Employee } from 'app/mock-api/common/employees/data.model' ;
import { filteringRoutes } from 'app/modules/admin/filtering/filtering.routing' ;
import { ColumnFiltersComponent } from './column-filters/column-filters.component' ;
import { FilterTypesComponent } from './filter-types/filter-types.component' ;
import { InLineFiltersComponent } from './in-line-filters/in-line-filters.component' ;
@ NgModule ({
declarations : [
ColumnFiltersComponent ,
FilterTypesComponent ,
InLineFiltersComponent
] ,
imports : [
CommonModule ,
RouterModule .forChild (filteringRoutes) ,
SharedModule ,
DikeDataGridModule
] ,
providers : [
{ provide : NUMERIC_FILTER_DEBOUNCE_TIME , useValue : 300 } ,
{
provide : CUSTOM_ROW_TEXT_FILTER_CONDITIONS ,
useFactory : () : CustomRowTextCaseFilterCondition < Employee > =>
new CustomRowTextCaseFilterCondition < Employee >()
.addExistingCondition ( ConditionType . ENDS_WITH )
} ,
{
provide : CUSTOM_TEXT_FILTER_CONDITIONS ,
useFactory : () : CustomTextCaseFilterCondition < Employee > =>
new CustomRowTextCaseFilterCondition ()
.addCondition ({
text : 'Custom Lower Case' ,
value : 'global-customLowerCaseText' ,
eval: (entry: Employee, dataColumnDef: DikeDataColumnDef<Employee, string>, values?: DikeTextFilter): boolean =>
dataColumnDef.getValue(entry).toLowerCase().includes(values.value)
})
}
]
})
export class FilteringModule { }