Skip to content

Commit a7bac6f

Browse files
committed
feat(h-grid): adv filtering improvements for load on demand
1 parent b846588 commit a7bac6f

File tree

4 files changed

+81
-79
lines changed

4 files changed

+81
-79
lines changed

projects/igniteui-angular/src/lib/data-operations/filtering-strategy.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ export abstract class BaseFilteringStrategy implements IFilteringStrategy {
4242
if (expr.searchTree) {
4343
const records = rec[expr.searchTree.entity];
4444
const shouldMatchRecords = expr.conditionName === 'inQuery';
45+
// if records is empty, it means that the child grid is not created yet
46+
if (!records || !records.length) {
47+
return true;
48+
}
49+
4550
for (let index = 0; index < records.length; index++) {
4651
const record = records[index];
4752
if ((shouldMatchRecords && this.matchRecord(record, expr.searchTree, grid, expr.searchTree.entity)) ||

projects/igniteui-angular/src/lib/grids/filtering/advanced-filtering/advanced-filtering-dialog.component.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ export class IgxAdvancedFilteringDialogComponent implements AfterViewInit, OnDes
227227
let childEntities;
228228
if (!rowIsland.autoGenerate) {
229229
fields = rowIsland.columnList.map(f => ({ field: f.field, dataType: f.dataType })) as FieldType[];
230-
} else {
230+
} else if (firstRowData) {
231231
const rowIslandFields = Object.keys(firstRowData).map(key => {
232232
if (firstRowData[key] instanceof Array) {
233233
return null;
@@ -242,10 +242,13 @@ export class IgxAdvancedFilteringDialogComponent implements AfterViewInit, OnDes
242242
}
243243

244244
const rowIslandChildEntities = rowIsland.childLayoutList.reduce((acc, childRowIsland) => {
245+
if (!firstRowData) {
246+
return null;
247+
}
245248
return acc.concat(this.generateChildEntity(childRowIsland, firstRowData[childRowIsland.key][0]));
246249
}, []);
247250

248-
if (rowIslandChildEntities.length > 0) {
251+
if (rowIslandChildEntities?.length > 0) {
249252
childEntities = rowIslandChildEntities;
250253
}
251254

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,29 @@
1-
<!-- <button (click)='setterBindingChange()'>Set rowSelection via binding</button>
2-
<button (click)='setterChange()'>Set rowSelection via setter on 1st row island</button> -->
3-
<igx-hierarchical-grid #grid1 [data]="remoteData" [isLoading]="true" [primaryKey]="'CustomerID'" [autoGenerate]="false" [height]="'800px'" [width]="'100%'" #hGrid [emptyGridMessage]="''">
1+
<igx-hierarchical-grid #grid1 [data]="remoteData" [isLoading]="true" [primaryKey]="'customerId'" [autoGenerate]="true" [height]="'800px'" [width]="'100%'" #hGrid [allowAdvancedFiltering]="true">
42
<igx-grid-toolbar>
5-
<igx-grid-toolbar-title>Parent Toolbar</igx-grid-toolbar-title>
6-
<igx-grid-toolbar-actions>
7-
<igx-grid-toolbar-hiding></igx-grid-toolbar-hiding>
8-
</igx-grid-toolbar-actions>
3+
<igx-grid-toolbar-title>Customers</igx-grid-toolbar-title>
94
</igx-grid-toolbar>
10-
<igx-column field="CustomerID"></igx-column>
5+
<!-- <igx-column field="customerId"></igx-column>
116
<igx-column field="CompanyName"></igx-column>
127
<igx-column field="ContactName"></igx-column>
138
<igx-column field="ContactTitle"></igx-column>
149
<igx-column field="Country"></igx-column>
15-
<igx-column field="Phone"></igx-column>
16-
<igx-row-island #rowIsland1 [key]="'Orders'" [primaryKey]="'OrderID'" [autoGenerate]="false" [rowSelection]='selectionMode' (gridCreated)="gridCreated($event, rowIsland1)" [emptyGridMessage]="''">
10+
<igx-column field="Phone"></igx-column> -->
11+
<igx-row-island #rowIsland1 [key]="'Orders'" [primaryKey]="'orderId'" [autoGenerate]="false" (gridCreated)="gridCreated($event, rowIsland1)">
1712
<igx-grid-toolbar *igxGridToolbar>
18-
<igx-grid-toolbar-title>Child Toolbar - Level 2</igx-grid-toolbar-title>
19-
<igx-grid-toolbar-actions>
20-
<igx-grid-toolbar-pinning></igx-grid-toolbar-pinning>
21-
</igx-grid-toolbar-actions>
13+
<igx-grid-toolbar-title>Orders</igx-grid-toolbar-title>
2214
</igx-grid-toolbar>
23-
<igx-column field="OrderID"></igx-column>
24-
<igx-column field="OrderDate"></igx-column>
25-
<igx-column field="ShipCountry"></igx-column>
26-
<igx-column field="ShipCity"></igx-column>
27-
<igx-column field="ShipAddress"></igx-column>
28-
<igx-row-island #rowIsland2 [key]="'Order_Details'" [primaryKey]="'ProductID'" [autoGenerate]="false" [rowSelection]='selectionMode' (gridCreated)="gridCreated($event, rowIsland2)" [emptyGridMessage]="''">
15+
<igx-column field="orderId"></igx-column>
16+
<igx-column field="customerId"></igx-column>
17+
<igx-column field="shipVia"></igx-column>
18+
<igx-row-island #rowIsland2 [key]="'Details'" [primaryKey]="'orderId'" [autoGenerate]="false" (gridCreated)="gridCreated($event, rowIsland2)">
2919
<igx-grid-toolbar *igxGridToolbar>
30-
<igx-grid-toolbar-title>Child Toolbar - Level 3</igx-grid-toolbar-title>
31-
<igx-grid-toolbar-actions>
32-
<igx-grid-toolbar-pinning></igx-grid-toolbar-pinning>
33-
<igx-grid-toolbar-hiding></igx-grid-toolbar-hiding>
34-
</igx-grid-toolbar-actions>
20+
<igx-grid-toolbar-title>Order Details</igx-grid-toolbar-title>
3521
</igx-grid-toolbar>
36-
<igx-column field="ProductID"></igx-column>
37-
<igx-column field="UnitPrice"></igx-column>
38-
<igx-column field="Quantity"></igx-column>
39-
<igx-column field="Discount"></igx-column>
22+
<igx-column field="orderId"></igx-column>
23+
<igx-column field="productId"></igx-column>
24+
<igx-column field="unitPrice"></igx-column>
25+
<igx-column field="quantity"></igx-column>
26+
<igx-column field="discount"></igx-column>
4027
</igx-row-island>
4128
</igx-row-island>
4229
</igx-hierarchical-grid>
Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,92 @@
1-
import { Component, ViewChild, AfterViewInit } from '@angular/core';
1+
import { Component, ViewChild, OnInit, ChangeDetectorRef } from '@angular/core';
22
import {
33
IgxRowIslandComponent,
44
IgxHierarchicalGridComponent,
55
IGridCreatedEventArgs,
6-
GridSelectionMode,
7-
IGX_HIERARCHICAL_GRID_DIRECTIVES
6+
IGX_HIERARCHICAL_GRID_DIRECTIVES,
7+
FilteringExpressionsTree,
8+
IgxStringFilteringOperand
89
} from 'igniteui-angular';
9-
import { RemoteService } from '../shared/remote.service';
10+
import { HttpClient } from '@angular/common/http';
11+
12+
const API_ENDPOINT = 'https://data-northwind.indigo.design';
1013

1114
@Component({
1215
selector: 'app-hierarchical-grid-remote-sample',
1316
templateUrl: 'hierarchical-grid-remote.sample.html',
1417
styleUrls: ['hierarchical-grid-remote.sample.scss'],
15-
providers: [RemoteService],
1618
imports: [IGX_HIERARCHICAL_GRID_DIRECTIVES]
1719
})
18-
export class HierarchicalGridRemoteSampleComponent implements AfterViewInit {
19-
@ViewChild('rowIsland1', { static: true })
20-
private rowIsland1: IgxRowIslandComponent;
21-
20+
export class HierarchicalGridRemoteSampleComponent implements OnInit {
2221
@ViewChild('hGrid', { static: true })
2322
private hGrid: IgxHierarchicalGridComponent;
2423

2524
public selectionMode;
2625
public remoteData = [];
2726
public primaryKeys = [
28-
{ name: 'CustomerID', type: 'string', level: 0 },
29-
{ name: 'OrderID', type: 'number', level: 1 },
30-
{ name: 'EmployeeID', type: 'number', level: 2 },
31-
{ name: 'ProductID', type: 'number', level: 2 }
27+
{ name: 'Customers', type: 'string', level: 0 },
28+
{ name: 'Orders', type: 'number', level: 1 },
29+
{ name: 'Details', type: 'number', level: 2 }
3230
];
3331

34-
constructor(private remoteService: RemoteService) {
35-
remoteService.url = 'https://services.odata.org/V4/Northwind/Northwind.svc/';
36-
37-
this.remoteService.urlBuilder = (dataState) => this.buildUrl(dataState);
38-
this.selectionMode = GridSelectionMode.none;
39-
}
40-
41-
public buildUrl(dataState) {
42-
let qS = '';
43-
if (dataState) {
44-
qS += `${dataState.key}?`;
32+
constructor(private http: HttpClient, private cdr: ChangeDetectorRef) {}
4533

46-
const level = dataState.level;
47-
if (level > 0) {
48-
const parentKey = this.primaryKeys.find((key) => key.level === level - 1);
49-
const parentID = typeof dataState.parentID !== 'object' ? dataState.parentID : dataState.parentID[parentKey.name];
34+
public ngOnInit() {
35+
const ordersTree = new FilteringExpressionsTree(0, undefined, 'Orders', ['shipVia']);
36+
ordersTree.filteringOperands.push({
37+
fieldName: 'shipVia',
38+
ignoreCase: false,
39+
conditionName: IgxStringFilteringOperand.instance().condition('equals').name,
40+
searchVal: 'AirCargo'
41+
});
5042

51-
if (parentKey.type === 'string') {
52-
qS += `$filter=${parentKey.name} eq '${parentID}'`;
53-
} else {
54-
qS += `$filter=${parentKey.name} eq ${parentID}`;
55-
}
56-
}
57-
}
58-
return `${this.remoteService.url}${qS}`;
43+
const customersTree = new FilteringExpressionsTree(0, undefined, 'Customers', ['customerId', 'companyName', 'contactName', 'contactTitle']);
44+
// customersTree.filteringOperands.push({
45+
// fieldName: 'customerId',
46+
// conditionName: IgxStringFilteringOperand.instance().condition('inQuery').name,
47+
// ignoreCase: false,
48+
// searchTree: ordersTree
49+
// });
50+
customersTree.filteringOperands.push({
51+
fieldName: 'customerId',
52+
ignoreCase: false,
53+
conditionName: IgxStringFilteringOperand.instance().condition('startsWith').name,
54+
searchVal: 'A'
55+
});
56+
this.hGrid.advancedFilteringExpressionsTree = customersTree;
5957
}
6058

6159
public ngAfterViewInit() {
62-
this.remoteService.getData({ parentID: null, level: 0, key: 'Customers' }, (data) => {
63-
this.remoteData = data['value'];
60+
this.hGrid.isLoading = true;
61+
this.http.post(`${API_ENDPOINT}/QueryBuilder/ExecuteQuery`, this.hGrid.advancedFilteringExpressionsTree).subscribe(data =>{
62+
console.log('data', data);
63+
this.remoteData = Object.values(data)[0];
6464
this.hGrid.isLoading = false;
65+
this.cdr.detectChanges();
66+
this.calculateColsInView();
6567
});
6668
}
6769

68-
public setterChange() {
69-
this.rowIsland1.rowSelection = this.rowIsland1.rowSelection === GridSelectionMode.multiple
70-
? GridSelectionMode.none : GridSelectionMode.multiple;
71-
}
72-
73-
public setterBindingChange() {
74-
this.selectionMode = this.selectionMode === GridSelectionMode.none ? GridSelectionMode.multiple : GridSelectionMode.none;
70+
private calculateColsInView() {
71+
this.hGrid.columns.forEach(column =>
72+
column.hidden = !this.hGrid.advancedFilteringExpressionsTree.returnFields.includes(column.field));
7573
}
7674

7775
public gridCreated(event: IGridCreatedEventArgs, rowIsland: IgxRowIslandComponent) {
7876
event.grid.isLoading = true;
79-
this.remoteService.getData({ parentID: event.parentID, level: rowIsland.level, key: rowIsland.key }, (data) => {
80-
event.grid.data = data['value'];
77+
const url = this.buildUrl(event, rowIsland);
78+
this.http.get(url).subscribe(data => {
79+
console.log('data', data);
80+
event.grid.data = Object.values(data);
8181
event.grid.isLoading = false;
82-
event.grid.cdr.detectChanges();
82+
this.cdr.detectChanges();
8383
});
8484
}
85+
86+
private buildUrl(event: IGridCreatedEventArgs, rowIsland: IgxRowIslandComponent) {
87+
const rowIslandKey = this.primaryKeys.find(key => key.level === rowIsland.level).name;
88+
const parentKey = (event.grid.parent as any).key ?? event.grid.parent.advancedFilteringExpressionsTree.entity;
89+
const url = `${API_ENDPOINT}/${parentKey}/${event.parentID}/${rowIslandKey}`;
90+
return url;
91+
}
8592
}

0 commit comments

Comments
 (0)