Skip to content

Commit 88294aa

Browse files
authored
Merge pull request #9265 from IgniteUI/dmdimitrov/fix-9050-11.1.x
fix(hierarchical-grid): fixed row island filtering - 11.1.x
2 parents 32f8315 + 7f9ad91 commit 88294aa

File tree

6 files changed

+165
-116
lines changed

6 files changed

+165
-116
lines changed

projects/igniteui-angular/src/lib/grids/api.service.ts

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ import { Injectable } from '@angular/core';
22
import { Subject } from 'rxjs';
33
import { cloneArray, isEqual, reverseMapper, mergeObjects } from '../core/utils';
44
import { DataUtil, DataType } from '../data-operations/data-util';
5-
import { IFilteringExpression } from '../data-operations/filtering-expression.interface';
65
import { ISortingExpression, SortingDirection } from '../data-operations/sorting-expression.interface';
76
import { IgxGridCellComponent } from './cell.component';
87
import { IgxGridBaseDirective } from './grid-base.directive';
98
import { IgxRowDirective } from './row.directive';
10-
import { IFilteringOperation } from '../data-operations/filtering-condition';
11-
import { IFilteringExpressionsTree, FilteringExpressionsTree } from '../data-operations/filtering-expressions-tree';
9+
import { IFilteringExpressionsTree } from '../data-operations/filtering-expressions-tree';
1210
import { Transaction, TransactionType, State } from '../services/transaction/transaction';
1311
import { IgxCell, IgxRow } from './selection/selection.service';
1412
import { GridType } from './common/grid.interface';
@@ -298,61 +296,6 @@ export class GridBaseAPIService <T extends IgxGridBaseDirective & GridType> {
298296
this.grid.sortingExpressions = sortingState;
299297
}
300298

301-
public filter(fieldName: string, term, conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree,
302-
ignoreCase: boolean) {
303-
const grid = this.grid;
304-
const filteringTree = grid.filteringExpressionsTree;
305-
this.grid.endEdit(false);
306-
307-
if (grid.paging) {
308-
grid.page = 0;
309-
}
310-
311-
const fieldFilterIndex = filteringTree.findIndex(fieldName);
312-
if (fieldFilterIndex > -1) {
313-
filteringTree.filteringOperands.splice(fieldFilterIndex, 1);
314-
}
315-
316-
this.prepare_filtering_expression(filteringTree, fieldName, term, conditionOrExpressionsTree, ignoreCase, fieldFilterIndex);
317-
grid.filteringExpressionsTree = filteringTree;
318-
}
319-
320-
public filter_global(term, condition, ignoreCase) {
321-
if (!condition) {
322-
return;
323-
}
324-
325-
const grid = this.grid;
326-
const filteringTree = grid.filteringExpressionsTree;
327-
grid.endEdit(false);
328-
if (grid.paging) {
329-
grid.page = 0;
330-
}
331-
332-
filteringTree.filteringOperands = [];
333-
for (const column of grid.columns) {
334-
this.prepare_filtering_expression(filteringTree, column.field, term,
335-
condition, ignoreCase || column.filteringIgnoreCase);
336-
}
337-
338-
grid.filteringExpressionsTree = filteringTree;
339-
}
340-
341-
public clear_filter(fieldName: string) {
342-
const grid = this.grid;
343-
grid.endEdit(false);
344-
const filteringState = grid.filteringExpressionsTree;
345-
const index = filteringState.findIndex(fieldName);
346-
347-
if (index > -1) {
348-
filteringState.filteringOperands.splice(index, 1);
349-
} else if (!fieldName) {
350-
filteringState.filteringOperands = [];
351-
}
352-
353-
grid.filteringExpressionsTree = filteringState;
354-
}
355-
356299
public clear_sort(fieldName: string) {
357300
const sortingState = this.grid.sortingExpressions;
358301
const index = sortingState.findIndex((expr) => expr.fieldName === fieldName);
@@ -527,48 +470,6 @@ export class GridBaseAPIService <T extends IgxGridBaseDirective & GridType> {
527470
return this.grid.expansionStates.get(rowID) !== expanded;
528471
}
529472

530-
/** Modifies the filteringState object to contain the newly added fitering conditions/expressions.
531-
* If createNewTree is true, filteringState will not be modified (because it directly affects the grid.filteringExpressionsTree),
532-
* but a new object is created and returned.
533-
*/
534-
public prepare_filtering_expression(
535-
filteringState: IFilteringExpressionsTree,
536-
fieldName: string,
537-
searchVal,
538-
conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree,
539-
ignoreCase: boolean,
540-
insertAtIndex = -1,
541-
createNewTree = false): FilteringExpressionsTree {
542-
543-
const oldExpressionsTreeIndex = filteringState.findIndex(fieldName);
544-
const expressionsTree = conditionOrExpressionsTree instanceof FilteringExpressionsTree ?
545-
conditionOrExpressionsTree as IFilteringExpressionsTree : null;
546-
const condition = conditionOrExpressionsTree instanceof FilteringExpressionsTree ?
547-
null : conditionOrExpressionsTree as IFilteringOperation;
548-
const newExpression: IFilteringExpression = { fieldName, searchVal, condition, ignoreCase };
549-
550-
const newExpressionsTree: FilteringExpressionsTree = createNewTree ?
551-
new FilteringExpressionsTree(filteringState.operator, filteringState.fieldName) : filteringState as FilteringExpressionsTree;
552-
553-
if (oldExpressionsTreeIndex === -1) {
554-
// no expressions tree found for this field
555-
if (expressionsTree) {
556-
if (insertAtIndex > -1) {
557-
newExpressionsTree.filteringOperands.splice(insertAtIndex, 0, expressionsTree);
558-
} else {
559-
newExpressionsTree.filteringOperands.push(expressionsTree);
560-
}
561-
} else if (condition) {
562-
// create expressions tree for this field and add the new expression to it
563-
const newExprTree: FilteringExpressionsTree = new FilteringExpressionsTree(filteringState.operator, fieldName);
564-
newExprTree.filteringOperands.push(newExpression);
565-
newExpressionsTree.filteringOperands.push(newExprTree);
566-
}
567-
}
568-
569-
return newExpressionsTree;
570-
}
571-
572473
public prepare_sorting_expression(stateCollections: Array<Array<any>>, expression: ISortingExpression) {
573474
if (expression.dir === SortingDirection.None) {
574475
stateCollections.forEach(state => {

projects/igniteui-angular/src/lib/grids/filtering/grid-filtering.service.ts

Lines changed: 107 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ import { takeUntil, first } from 'rxjs/operators';
77
import { IForOfState } from '../../directives/for-of/for_of.directive';
88
import { IgxColumnComponent } from '../columns/column.component';
99
import { IFilteringOperation } from '../../data-operations/filtering-condition';
10-
import { GridBaseAPIService } from '../api.service';
1110
import { IColumnResizeEventArgs, IFilteringEventArgs } from '../common/events';
12-
import { GridType } from '../common/grid.interface';
1311
import { OverlaySettings, PositionSettings, VerticalAlignment } from '../../services/overlay/utilities';
1412
import { IgxOverlayService } from '../../services/overlay/overlay';
1513
import { useAnimation } from '@angular/animations';
@@ -55,8 +53,7 @@ export class IgxFilteringService implements OnDestroy {
5553
private column;
5654
private lastActiveNode;
5755

58-
constructor(private gridAPI: GridBaseAPIService<IgxGridBaseDirective & GridType>, private _moduleRef: NgModuleRef<any>,
59-
private iconService: IgxIconService, private _overlayService: IgxOverlayService) {}
56+
constructor(private _moduleRef: NgModuleRef<any>, private iconService: IgxIconService, private _overlayService: IgxOverlayService) {}
6057

6158
public ngOnDestroy(): void {
6259
this.destroy$.next(true);
@@ -202,7 +199,7 @@ export class IgxFilteringService implements OnDestroy {
202199

203200
const grid = this.grid;
204201

205-
const col = this.gridAPI.get_column_by_name(field);
202+
const col = grid.getColumnByName(field);
206203
const filteringIgnoreCase = ignoreCase || (col ? col.filteringIgnoreCase : false);
207204

208205
const filteringTree = grid.filteringExpressionsTree;
@@ -213,7 +210,7 @@ export class IgxFilteringService implements OnDestroy {
213210
filteringTree.filteringOperands.splice(fieldFilterIndex, 1);
214211
}
215212
const newFilteringTree: FilteringExpressionsTree =
216-
this.gridAPI.prepare_filtering_expression(filteringTree, field, value, conditionOrExpressionTree,
213+
this.prepare_filtering_expression(filteringTree, field, value, conditionOrExpressionTree,
217214
filteringIgnoreCase, fieldFilterIndex, true);
218215

219216
const eventArgs: IFilteringEventArgs = { owner: grid,
@@ -225,29 +222,50 @@ export class IgxFilteringService implements OnDestroy {
225222
}
226223

227224
if (conditionOrExpressionTree) {
228-
this.gridAPI.filter(field, value, conditionOrExpressionTree, filteringIgnoreCase);
225+
this.filter_internal(field, value, conditionOrExpressionTree, filteringIgnoreCase);
229226
} else {
230227
const expressionsTreeForColumn = this.grid.filteringExpressionsTree.find(field);
231228
if (!expressionsTreeForColumn) {
232229
throw new Error('Invalid condition or Expression Tree!');
233230
} else if (expressionsTreeForColumn instanceof FilteringExpressionsTree) {
234-
this.gridAPI.filter(field, value, expressionsTreeForColumn, filteringIgnoreCase );
231+
this.filter_internal(field, value, expressionsTreeForColumn, filteringIgnoreCase );
235232
} else {
236233
const expressionForColumn = expressionsTreeForColumn as IFilteringExpression;
237-
this.gridAPI.filter(field, value, expressionForColumn.condition, filteringIgnoreCase );
234+
this.filter_internal(field, value, expressionForColumn.condition, filteringIgnoreCase );
238235
}
239236
}
240237
const doneEventArgs = this.grid.filteringExpressionsTree.find(field) as FilteringExpressionsTree;
241238
// Wait for the change detection to update filtered data through the pipes and then emit the event.
242239
requestAnimationFrame(() => this.grid.onFilteringDone.emit(doneEventArgs));
243240
}
244241

242+
public filter_global(term, condition, ignoreCase) {
243+
if (!condition) {
244+
return;
245+
}
246+
247+
const grid = this.grid;
248+
const filteringTree = grid.filteringExpressionsTree;
249+
grid.endEdit(false);
250+
if (grid.paging) {
251+
grid.page = 0;
252+
}
253+
254+
filteringTree.filteringOperands = [];
255+
for (const column of grid.columns) {
256+
this.prepare_filtering_expression(filteringTree, column.field, term,
257+
condition, ignoreCase || column.filteringIgnoreCase);
258+
}
259+
260+
grid.filteringExpressionsTree = filteringTree;
261+
}
262+
245263
/**
246264
* Clears the filter of a given column if name is provided. Otherwise clears the filters of all columns.
247265
*/
248266
public clearFilter(field: string): void {
249267
if (field) {
250-
const column = this.gridAPI.get_column_by_name(field);
268+
const column = this.grid.getColumnByName(field);
251269
if (!column) {
252270
return;
253271
}
@@ -265,7 +283,7 @@ export class IgxFilteringService implements OnDestroy {
265283
}
266284

267285
this.isFiltering = true;
268-
this.gridAPI.clear_filter(field);
286+
this.clear_filter(field);
269287

270288
// Wait for the change detection to update filtered data through the pipes and then emit the event.
271289
requestAnimationFrame(() => this.grid.onFilteringDone.emit(null));
@@ -283,6 +301,21 @@ export class IgxFilteringService implements OnDestroy {
283301
this.isFiltering = false;
284302
}
285303

304+
public clear_filter(fieldName: string) {
305+
const grid = this.grid;
306+
grid.endEdit(false);
307+
const filteringState = grid.filteringExpressionsTree;
308+
const index = filteringState.findIndex(fieldName);
309+
310+
if (index > -1) {
311+
filteringState.filteringOperands.splice(index, 1);
312+
} else if (!fieldName) {
313+
filteringState.filteringOperands = [];
314+
}
315+
316+
grid.filteringExpressionsTree = filteringState;
317+
}
318+
286319
/**
287320
* Filters all the `IgxColumnComponent` in the `IgxGridComponent` with the same condition.
288321
*/
@@ -296,7 +329,7 @@ export class IgxFilteringService implements OnDestroy {
296329
const newFilteringTree = new FilteringExpressionsTree(filteringTree.operator, filteringTree.fieldName);
297330

298331
for (const column of grid.columns) {
299-
this.gridAPI.prepare_filtering_expression(newFilteringTree, column.field, value, condition,
332+
this.prepare_filtering_expression(newFilteringTree, column.field, value, condition,
300333
ignoreCase || column.filteringIgnoreCase);
301334
}
302335

@@ -515,6 +548,68 @@ export class IgxFilteringService implements OnDestroy {
515548
return true;
516549
}
517550

551+
private filter_internal(fieldName: string, term, conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree,
552+
ignoreCase: boolean) {
553+
const grid = this.grid;
554+
const filteringTree = grid.filteringExpressionsTree;
555+
this.grid.endEdit(false);
556+
557+
if (grid.paging) {
558+
grid.page = 0;
559+
}
560+
561+
const fieldFilterIndex = filteringTree.findIndex(fieldName);
562+
if (fieldFilterIndex > -1) {
563+
filteringTree.filteringOperands.splice(fieldFilterIndex, 1);
564+
}
565+
566+
this.prepare_filtering_expression(filteringTree, fieldName, term, conditionOrExpressionsTree, ignoreCase, fieldFilterIndex);
567+
grid.filteringExpressionsTree = filteringTree;
568+
}
569+
570+
/** Modifies the filteringState object to contain the newly added fitering conditions/expressions.
571+
* If createNewTree is true, filteringState will not be modified (because it directly affects the grid.filteringExpressionsTree),
572+
* but a new object is created and returned.
573+
*/
574+
private prepare_filtering_expression(
575+
filteringState: IFilteringExpressionsTree,
576+
fieldName: string,
577+
searchVal,
578+
conditionOrExpressionsTree: IFilteringOperation | IFilteringExpressionsTree,
579+
ignoreCase: boolean,
580+
insertAtIndex = -1,
581+
createNewTree = false): FilteringExpressionsTree {
582+
583+
const oldExpressionsTreeIndex = filteringState.findIndex(fieldName);
584+
const expressionsTree = conditionOrExpressionsTree instanceof FilteringExpressionsTree ?
585+
conditionOrExpressionsTree as IFilteringExpressionsTree : null;
586+
const condition = conditionOrExpressionsTree instanceof FilteringExpressionsTree ?
587+
null : conditionOrExpressionsTree as IFilteringOperation;
588+
const newExpression: IFilteringExpression = { fieldName, searchVal, condition, ignoreCase };
589+
590+
const newExpressionsTree: FilteringExpressionsTree = createNewTree ?
591+
new FilteringExpressionsTree(filteringState.operator, filteringState.fieldName) : filteringState as FilteringExpressionsTree;
592+
593+
if (oldExpressionsTreeIndex === -1) {
594+
// no expressions tree found for this field
595+
if (expressionsTree) {
596+
if (insertAtIndex > -1) {
597+
newExpressionsTree.filteringOperands.splice(insertAtIndex, 0, expressionsTree);
598+
} else {
599+
newExpressionsTree.filteringOperands.push(expressionsTree);
600+
}
601+
} else if (condition) {
602+
// create expressions tree for this field and add the new expression to it
603+
const newExprTree: FilteringExpressionsTree = new FilteringExpressionsTree(filteringState.operator, fieldName);
604+
newExprTree.filteringOperands.push(newExpression);
605+
newExpressionsTree.filteringOperands.push(newExprTree);
606+
}
607+
}
608+
609+
return newExpressionsTree;
610+
}
611+
612+
518613
private isFilteringTreeComplex(expressions: IFilteringExpressionsTree | IFilteringExpression): boolean {
519614
if (!expressions) {
520615
return false;

projects/igniteui-angular/src/lib/grids/grid-base.directive.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6430,7 +6430,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements
64306430
this.gridAPI.clear_groupby(record.item.field);
64316431

64326432
// Clear Filtering
6433-
this.gridAPI.clear_filter(record.item.field);
6433+
this.filteringService.clear_filter(record.item.field);
64346434

64356435
// Close filter row
64366436
if (this.filteringService.isFilterRowVisible

projects/igniteui-angular/src/lib/grids/grid/grid-cell-editing.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ describe('IgxGrid - Cell Editing #grid', () => {
11121112

11131113
grid.filter('fullName', 'Al', IgxStringFilteringOperand.instance().condition('equals'));
11141114
fixture.detectChanges();
1115-
cell.gridAPI.clear_filter('fullName');
1115+
grid.clearFilter('fullName');
11161116
fixture.detectChanges();
11171117

11181118
cell = grid.getCellByColumn(0, 'fullName');

0 commit comments

Comments
 (0)