@@ -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 ) ;
@@ -203,7 +200,7 @@ export class IgxFilteringService implements OnDestroy {
203200
204201 const grid = this . grid ;
205202
206- const col = this . gridAPI . get_column_by_name ( field ) ;
203+ const col = grid . getColumnByName ( field ) ;
207204 const filteringIgnoreCase = ignoreCase || ( col ? col . filteringIgnoreCase : false ) ;
208205
209206 const filteringTree = grid . filteringExpressionsTree ;
@@ -214,7 +211,7 @@ export class IgxFilteringService implements OnDestroy {
214211 filteringTree . filteringOperands . splice ( fieldFilterIndex , 1 ) ;
215212 }
216213 const newFilteringTree : FilteringExpressionsTree =
217- this . gridAPI . prepare_filtering_expression ( filteringTree , field , value , conditionOrExpressionTree ,
214+ this . prepare_filtering_expression ( filteringTree , field , value , conditionOrExpressionTree ,
218215 filteringIgnoreCase , fieldFilterIndex , true ) ;
219216
220217 const eventArgs : IFilteringEventArgs = { owner : grid ,
@@ -226,29 +223,50 @@ export class IgxFilteringService implements OnDestroy {
226223 }
227224
228225 if ( conditionOrExpressionTree ) {
229- this . gridAPI . filter ( field , value , conditionOrExpressionTree , filteringIgnoreCase ) ;
226+ this . filter_internal ( field , value , conditionOrExpressionTree , filteringIgnoreCase ) ;
230227 } else {
231228 const expressionsTreeForColumn = this . grid . filteringExpressionsTree . find ( field ) ;
232229 if ( ! expressionsTreeForColumn ) {
233230 throw new Error ( 'Invalid condition or Expression Tree!' ) ;
234231 } else if ( expressionsTreeForColumn instanceof FilteringExpressionsTree ) {
235- this . gridAPI . filter ( field , value , expressionsTreeForColumn , filteringIgnoreCase ) ;
232+ this . filter_internal ( field , value , expressionsTreeForColumn , filteringIgnoreCase ) ;
236233 } else {
237234 const expressionForColumn = expressionsTreeForColumn as IFilteringExpression ;
238- this . gridAPI . filter ( field , value , expressionForColumn . condition , filteringIgnoreCase ) ;
235+ this . filter_internal ( field , value , expressionForColumn . condition , filteringIgnoreCase ) ;
239236 }
240237 }
241238 const doneEventArgs = this . grid . filteringExpressionsTree . find ( field ) as FilteringExpressionsTree ;
242239 // Wait for the change detection to update filtered data through the pipes and then emit the event.
243240 requestAnimationFrame ( ( ) => this . grid . onFilteringDone . emit ( doneEventArgs ) ) ;
244241 }
245242
243+ public filter_global ( term , condition , ignoreCase ) {
244+ if ( ! condition ) {
245+ return ;
246+ }
247+
248+ const grid = this . grid ;
249+ const filteringTree = grid . filteringExpressionsTree ;
250+ grid . crudService . endEdit ( false ) ;
251+ if ( grid . paging ) {
252+ grid . page = 0 ;
253+ }
254+
255+ filteringTree . filteringOperands = [ ] ;
256+ for ( const column of grid . columns ) {
257+ this . prepare_filtering_expression ( filteringTree , column . field , term ,
258+ condition , ignoreCase || column . filteringIgnoreCase ) ;
259+ }
260+
261+ grid . filteringExpressionsTree = filteringTree ;
262+ }
263+
246264 /**
247265 * Clears the filter of a given column if name is provided. Otherwise clears the filters of all columns.
248266 */
249267 public clearFilter ( field : string ) : void {
250268 if ( field ) {
251- const column = this . gridAPI . get_column_by_name ( field ) ;
269+ const column = this . grid . getColumnByName ( field ) ;
252270 if ( ! column ) {
253271 return ;
254272 }
@@ -266,7 +284,7 @@ export class IgxFilteringService implements OnDestroy {
266284 }
267285
268286 this . isFiltering = true ;
269- this . gridAPI . clear_filter ( field ) ;
287+ this . clear_filter ( field ) ;
270288
271289 // Wait for the change detection to update filtered data through the pipes and then emit the event.
272290 requestAnimationFrame ( ( ) => this . grid . onFilteringDone . emit ( null ) ) ;
@@ -284,6 +302,21 @@ export class IgxFilteringService implements OnDestroy {
284302 this . isFiltering = false ;
285303 }
286304
305+ public clear_filter ( fieldName : string ) {
306+ const grid = this . grid ;
307+ grid . crudService . endEdit ( false ) ;
308+ const filteringState = grid . filteringExpressionsTree ;
309+ const index = filteringState . findIndex ( fieldName ) ;
310+
311+ if ( index > - 1 ) {
312+ filteringState . filteringOperands . splice ( index , 1 ) ;
313+ } else if ( ! fieldName ) {
314+ filteringState . filteringOperands = [ ] ;
315+ }
316+
317+ grid . filteringExpressionsTree = filteringState ;
318+ }
319+
287320 /**
288321 * Filters all the `IgxColumnComponent` in the `IgxGridComponent` with the same condition.
289322 */
@@ -297,7 +330,7 @@ export class IgxFilteringService implements OnDestroy {
297330 const newFilteringTree = new FilteringExpressionsTree ( filteringTree . operator , filteringTree . fieldName ) ;
298331
299332 for ( const column of grid . columns ) {
300- this . gridAPI . prepare_filtering_expression ( newFilteringTree , column . field , value , condition ,
333+ this . prepare_filtering_expression ( newFilteringTree , column . field , value , condition ,
301334 ignoreCase || column . filteringIgnoreCase ) ;
302335 }
303336
@@ -516,6 +549,68 @@ export class IgxFilteringService implements OnDestroy {
516549 return true ;
517550 }
518551
552+ private filter_internal ( fieldName : string , term , conditionOrExpressionsTree : IFilteringOperation | IFilteringExpressionsTree ,
553+ ignoreCase : boolean ) {
554+ const grid = this . grid ;
555+ const filteringTree = grid . filteringExpressionsTree ;
556+ this . grid . crudService . endEdit ( false ) ;
557+
558+ if ( grid . paging ) {
559+ grid . page = 0 ;
560+ }
561+
562+ const fieldFilterIndex = filteringTree . findIndex ( fieldName ) ;
563+ if ( fieldFilterIndex > - 1 ) {
564+ filteringTree . filteringOperands . splice ( fieldFilterIndex , 1 ) ;
565+ }
566+
567+ this . prepare_filtering_expression ( filteringTree , fieldName , term , conditionOrExpressionsTree , ignoreCase , fieldFilterIndex ) ;
568+ grid . filteringExpressionsTree = filteringTree ;
569+ }
570+
571+ /** Modifies the filteringState object to contain the newly added fitering conditions/expressions.
572+ * If createNewTree is true, filteringState will not be modified (because it directly affects the grid.filteringExpressionsTree),
573+ * but a new object is created and returned.
574+ */
575+ private prepare_filtering_expression (
576+ filteringState : IFilteringExpressionsTree ,
577+ fieldName : string ,
578+ searchVal ,
579+ conditionOrExpressionsTree : IFilteringOperation | IFilteringExpressionsTree ,
580+ ignoreCase : boolean ,
581+ insertAtIndex = - 1 ,
582+ createNewTree = false ) : FilteringExpressionsTree {
583+
584+ const oldExpressionsTreeIndex = filteringState . findIndex ( fieldName ) ;
585+ const expressionsTree = conditionOrExpressionsTree instanceof FilteringExpressionsTree ?
586+ conditionOrExpressionsTree as IFilteringExpressionsTree : null ;
587+ const condition = conditionOrExpressionsTree instanceof FilteringExpressionsTree ?
588+ null : conditionOrExpressionsTree as IFilteringOperation ;
589+ const newExpression : IFilteringExpression = { fieldName, searchVal, condition, ignoreCase } ;
590+
591+ const newExpressionsTree : FilteringExpressionsTree = createNewTree ?
592+ new FilteringExpressionsTree ( filteringState . operator , filteringState . fieldName ) : filteringState as FilteringExpressionsTree ;
593+
594+ if ( oldExpressionsTreeIndex === - 1 ) {
595+ // no expressions tree found for this field
596+ if ( expressionsTree ) {
597+ if ( insertAtIndex > - 1 ) {
598+ newExpressionsTree . filteringOperands . splice ( insertAtIndex , 0 , expressionsTree ) ;
599+ } else {
600+ newExpressionsTree . filteringOperands . push ( expressionsTree ) ;
601+ }
602+ } else if ( condition ) {
603+ // create expressions tree for this field and add the new expression to it
604+ const newExprTree : FilteringExpressionsTree = new FilteringExpressionsTree ( filteringState . operator , fieldName ) ;
605+ newExprTree . filteringOperands . push ( newExpression ) ;
606+ newExpressionsTree . filteringOperands . push ( newExprTree ) ;
607+ }
608+ }
609+
610+ return newExpressionsTree ;
611+ }
612+
613+
519614 private isFilteringTreeComplex ( expressions : IFilteringExpressionsTree | IFilteringExpression ) : boolean {
520615 if ( ! expressions ) {
521616 return false ;
0 commit comments