@@ -7,9 +7,7 @@ import { takeUntil, first } from 'rxjs/operators';
77import { IForOfState } from '../../directives/for-of/for_of.directive' ;
88import { IgxColumnComponent } from '../columns/column.component' ;
99import { IFilteringOperation } from '../../data-operations/filtering-condition' ;
10- import { GridBaseAPIService } from '../api.service' ;
1110import { IColumnResizeEventArgs , IFilteringEventArgs } from '../common/events' ;
12- import { GridType } from '../common/grid.interface' ;
1311import { OverlaySettings , PositionSettings , VerticalAlignment } from '../../services/overlay/utilities' ;
1412import { IgxOverlayService } from '../../services/overlay/overlay' ;
1513import { 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 ;
0 commit comments