@@ -11,7 +11,7 @@ import {
1111import { IgxInputDirective } from '../../../directives/input/input.directive' ;
1212import { DisplayDensity } from '../../../core/density' ;
1313import { IgxForOfDirective } from '../../../directives/for-of/for_of.directive' ;
14- import { IgxGridExcelStyleFilteringComponent } from './grid.excel-style-filtering.component' ;
14+ import { IgxGridExcelStyleFilteringComponent , FilterListItem } from './grid.excel-style-filtering.component' ;
1515import { FilteringExpressionsTree } from '../../../data-operations/filtering-expressions-tree' ;
1616import { FilteringLogic } from '../../../data-operations/filtering-expression.interface' ;
1717import { DataType } from '../../../data-operations/data-util' ;
@@ -23,6 +23,7 @@ import { Subject } from 'rxjs';
2323import { IgxListComponent } from '../../../list/public_api' ;
2424import { IChangeCheckboxEventArgs } from '../../../checkbox/checkbox.component' ;
2525import { takeUntil } from 'rxjs/operators' ;
26+ import { KEYS } from '../../../core/utils' ;
2627
2728@Directive ( {
2829 selector : '[igxExcelStyleLoading]'
@@ -42,8 +43,30 @@ export class IgxExcelStyleLoadingValuesTemplateDirective {
4243export class IgxExcelStyleSearchComponent implements AfterViewInit , OnDestroy {
4344 private static readonly filterOptimizationThreshold = 2 ;
4445 private _isLoading ;
46+ private _addToCurrentFilter : FilterListItem ;
4547 private destroy$ = new Subject < boolean > ( ) ;
4648
49+ /**
50+ * @hidden @internal
51+ */
52+ public get addToCurrentFilter ( ) : FilterListItem {
53+ if ( ! this . _addToCurrentFilter ) {
54+ const addToCurrentFilterItem = {
55+ isSelected : false ,
56+ isFiltered : false ,
57+ indeterminate : false ,
58+ isSpecial : true ,
59+ isBlanks : false ,
60+ value : this . esf . grid . resourceStrings . igx_grid_excel_add_to_filter ,
61+ label : this . esf . grid . resourceStrings . igx_grid_excel_add_to_filter
62+ } ;
63+
64+ this . _addToCurrentFilter = addToCurrentFilterItem ;
65+ }
66+
67+ return this . _addToCurrentFilter ;
68+ }
69+
4770 /**
4871 * @hidden @internal
4972 */
@@ -66,6 +89,11 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy {
6689 */
6790 public searchValue : any ;
6891
92+ /**
93+ * @hidden @internal
94+ */
95+ public displayedListData : FilterListItem [ ] ;
96+
6997 /**
7098 * @hidden @internal
7199 */
@@ -106,13 +134,6 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy {
106134 }
107135 }
108136
109- /**
110- * @hidden @internal
111- */
112- get applyButtonDisabled ( ) {
113- return this . esf . listData [ 0 ] && ! this . esf . listData [ 0 ] . isSelected && ! this . esf . listData [ 0 ] . indeterminate ;
114- }
115-
116137 constructor ( public cdr : ChangeDetectorRef , public esf : IgxGridExcelStyleFilteringComponent ) {
117138 esf . loadingStart . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( ( ) => {
118139 this . isLoading = true ;
@@ -129,6 +150,10 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy {
129150 esf . columnChange . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( ( ) => {
130151 this . virtDir . resetScrollPosition ( ) ;
131152 } ) ;
153+
154+ esf . listDataLoaded . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( ( ) => {
155+ this . filterListData ( ) ;
156+ } ) ;
132157 }
133158
134159 public ngAfterViewInit ( ) {
@@ -154,28 +179,38 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy {
154179 */
155180 public clearInput ( ) {
156181 this . searchValue = null ;
182+ this . filterListData ( ) ;
157183 }
158184
159185 /**
160186 * @hidden @internal
161187 */
162188 public onCheckboxChange ( eventArgs : IChangeCheckboxEventArgs ) {
163- const selectedIndex = this . esf . listData . indexOf ( eventArgs . checkbox . value ) ;
189+ const selectedIndex = this . displayedListData . indexOf ( eventArgs . checkbox . value ) ;
190+ const selectAllBtn = this . displayedListData [ 0 ] ;
191+
164192 if ( selectedIndex === 0 ) {
165- this . esf . listData . forEach ( element => {
193+ this . displayedListData . forEach ( element => {
194+ if ( element === this . addToCurrentFilter ) { return ; }
166195 element . isSelected = eventArgs . checked ;
167- this . esf . listData [ 0 ] . indeterminate = false ;
168196 } ) ;
197+
198+ selectAllBtn . indeterminate = false ;
169199 } else {
170200 eventArgs . checkbox . value . isSelected = eventArgs . checked ;
171- if ( ! this . esf . listData . slice ( 1 , this . esf . listData . length ) . find ( el => el . isSelected === false ) ) {
172- this . esf . listData [ 0 ] . indeterminate = false ;
173- this . esf . listData [ 0 ] . isSelected = true ;
174- } else if ( ! this . esf . listData . slice ( 1 , this . esf . listData . length ) . find ( el => el . isSelected === true ) ) {
175- this . esf . listData [ 0 ] . indeterminate = false ;
176- this . esf . listData [ 0 ] . isSelected = false ;
201+ const indexToStartSlicing = this . displayedListData . indexOf ( this . addToCurrentFilter ) > - 1 ? 2 : 1 ;
202+
203+ const slicedArray =
204+ this . displayedListData . slice ( indexToStartSlicing , this . displayedListData . length ) ;
205+
206+ if ( ! slicedArray . find ( el => el . isSelected === false ) ) {
207+ selectAllBtn . indeterminate = false ;
208+ selectAllBtn . isSelected = true ;
209+ } else if ( ! slicedArray . find ( el => el . isSelected === true ) ) {
210+ selectAllBtn . indeterminate = false ;
211+ selectAllBtn . isSelected = false ;
177212 } else {
178- this . esf . listData [ 0 ] . indeterminate = true ;
213+ selectAllBtn . indeterminate = true ;
179214 }
180215 }
181216 eventArgs . checkbox . nativeCheckbox . nativeElement . blur ( ) ;
@@ -203,12 +238,84 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy {
203238 }
204239 }
205240
241+ /**
242+ * @hidden @internal
243+ */
244+ get applyButtonDisabled ( ) : boolean {
245+ return this . esf . listData [ 0 ] && ! this . esf . listData [ 0 ] . isSelected && ! this . esf . listData [ 0 ] . indeterminate ||
246+ this . displayedListData && this . displayedListData . length === 0 ;
247+ }
248+
249+ /**
250+ * @hidden @internal
251+ */
252+ public onInputKeyDown ( event ) : void {
253+ if ( event . key === KEYS . ENTER ) {
254+ event . preventDefault ( ) ;
255+ this . applyFilter ( ) ;
256+ }
257+ }
258+
259+ /**
260+ * @hidden @internal
261+ */
262+ public filterListData ( ) : void {
263+ if ( ! this . esf . listData || ! this . esf . listData . length ) {
264+ this . displayedListData = [ ] ;
265+
266+ return ;
267+ }
268+
269+ const searchAllBtn = this . esf . listData [ 0 ] ;
270+
271+ if ( ! this . searchValue ) {
272+ const anyFiltered = this . esf . listData . some ( i => i . isFiltered ) ;
273+ const anyUnfiltered = this . esf . listData . some ( i => ! i . isFiltered ) ;
274+
275+ if ( anyFiltered && anyUnfiltered ) {
276+ searchAllBtn . indeterminate = true ;
277+ }
278+
279+ this . esf . listData . forEach ( i => i . isSelected = i . isFiltered ) ;
280+ this . displayedListData = this . esf . listData ;
281+ searchAllBtn . label = this . esf . grid . resourceStrings . igx_grid_excel_select_all ;
282+
283+ return ;
284+ }
285+
286+ const searchVal = this . searchValue . toLowerCase ( ) ;
287+
288+ this . displayedListData = this . esf . listData . filter ( ( it , i ) => ( i === 0 && it . isSpecial ) ||
289+ ( it . label !== null && it . label !== undefined ) &&
290+ ! it . isBlanks &&
291+ it . label . toString ( ) . toLowerCase ( ) . indexOf ( searchVal ) > - 1 ) ;
292+
293+ this . esf . listData . forEach ( i => i . isSelected = false ) ;
294+ this . displayedListData . forEach ( i => i . isSelected = true ) ;
295+
296+ this . displayedListData . splice ( 1 , 0 , this . addToCurrentFilter ) ;
297+
298+ searchAllBtn . indeterminate = false ;
299+ searchAllBtn . label = this . esf . grid . resourceStrings . igx_grid_excel_select_all_search_results ;
300+
301+ if ( this . displayedListData . length === 2 ) {
302+ this . displayedListData = [ ] ;
303+ }
304+ }
305+
206306 /**
207307 * @hidden @internal
208308 */
209309 public applyFilter ( ) {
210310 const filterTree = new FilteringExpressionsTree ( FilteringLogic . Or , this . esf . column . field ) ;
211- const selectedItems = this . esf . listData . slice ( 1 , this . esf . listData . length ) . filter ( el => el . isSelected === true ) ;
311+
312+ const item = this . displayedListData [ 1 ] ;
313+ const addToCurrentFilterOptionVisible = item === this . addToCurrentFilter ;
314+
315+ const selectedItems = addToCurrentFilterOptionVisible && item . isSelected ?
316+ this . esf . listData . slice ( 1 , this . esf . listData . length ) . filter ( el => el . isSelected || el . isFiltered ) :
317+ this . esf . listData . slice ( 1 , this . esf . listData . length ) . filter ( el => el . isSelected ) ;
318+
212319 const unselectedItem = this . esf . listData . slice ( 1 , this . esf . listData . length ) . find ( el => el . isSelected === false ) ;
213320
214321 if ( unselectedItem ) {
0 commit comments