AG Grid's Infinite Row Model (infinite scroll)
for Entity Framework Core implemented with System.Linq.Dynamic
.
- Add
AgGrid.InfiniteRowModel
(orAgGrid.InfiniteRowModel.EntityFrameworkCore
for async methods) package to your ASP.NET Core project. - Call
GetInfiniteRowModelBlock
extension method on chosenDbSet
/IQueryable
and passIGetRowsParams
(withoutcontext
) from AG Grid'sdatasource
. You can pass deserialized object (of typeGetRowsParams
) or JSON string. - Pass the result (
rowsThisBlock
andlastRow
) tosuccessCallback
of yourdatasource
(see sample code below).
More in sample/AgGrid.InfiniteRowModel.Sample
[HttpGet]
public InfiniteRowModelResult<User> Get(string query)
{
return _dbContext.Users.GetInfiniteRowModelBlock(query);
}
nullFilterOption: IFilterOptionDef = {
displayKey: 'null',
displayName: 'Null',
test: (filterValues, cellValue) => cellValue === null,
numberOfInputs: 0
};
gridOptions: GridOptions = {
defaultColDef: {
sortable: true,
floatingFilter: true
},
frameworkComponents: {
'agBooleanColumnFilter': AgBooleanColumnFilterComponent
},
columnDefs: [
{
headerName: 'Full name',
field: 'fullName',
filter: 'agTextColumnFilter',
filterParams: {
filterOptions: ['equals', 'notEqual', 'contains', 'notContains', 'startsWith', 'endsWith', this.nullFilterOption ]
}
},
{ headerName: 'Registered on', field: 'registeredOn', filter: 'agDateColumnFilter' },
{ headerName: 'Age', field: 'age', filter: 'agNumberColumnFilter' },
{ headerName: 'Is verified', field: 'isVerified', filter: 'agBooleanColumnFilter' }
],
rowModelType: 'infinite',
datasource: {
getRows: (params: IGetRowsParams) => {
this.userService.getUsers(JSON.stringify(params))
.subscribe(
result => params.successCallback(result.rowsThisBlock, result.lastRow),
() => params.failCallback());
}
}
};
getUsers(query: string): Observable<InfiniteRowModelResult<User>> {
return this.httpClient.get<InfiniteRowModelResult<User>>(this.baseUrl + 'api/Users', {
params: {
query: query
}
});
}
This package supports all three built-in simple filters:
- Text Filter,
- Number Filter,
- Date Filter.
You can use custom filter option with simple filters to allow filtering by null.
It also provides support for custom boolean filter implementation. You don't have to use the same filter but your filter model has to match BooleanFilterModel
interface (below).
@Component({
selector: 'app-ag-boolean-column-filter',
templateUrl: './ag-boolean-column-filter.component.html',
providers: [
{ provide: MAT_CHECKBOX_CLICK_ACTION, useValue: 'noop' }
]
})
export class AgBooleanColumnFilterComponent implements AgFilterComponent {
private params: IFilterParams;
value: boolean | null = null;
agInit(params: IFilterParams): void {
this.params = params;
}
onCheckboxClicked(): void {
if (this.value === null) {
this.value = true;
} else if (this.value === true) {
this.value = false;
} else if (this.value === false) {
this.value = null;
}
this.updateFilter();
}
isFilterActive(): boolean {
return this.value !== null;
}
doesFilterPass(params: IDoesFilterPassParams): boolean {
throw new Error(`Not implemented. Seems to be unnecessary since we're doing all our filtering on the server side.`);
}
getModel(): BooleanFilterModel {
if (!this.isFilterActive()) {
return null;
}
return {
filter: this.value,
filterType: 'boolean',
type: 'equals'
};
}
setModel(model: BooleanFilterModel) {
if (!model) {
this.value = null;
return;
}
this.value = model.filter;
}
updateFilter() {
this.params.filterChangedCallback();
}
getModelAsString(): string {
return this.value.toString();
}
}
<div style="padding: 20px 20px 10px 20px;">
<mat-checkbox color="primary" [checked]="value" [indeterminate]="value === null" (click)="onCheckboxClicked()">
</mat-checkbox>
</div>
export interface BooleanFilterModel {
filter: boolean;
filterType: 'boolean';
type: 'equals' | 'notEqual';
}
- Just run it. Database will be created and seeded on app startup.