diff --git a/projects/igniteui-angular/src/lib/directives/text-highlight/text-highlight.directive.ts b/projects/igniteui-angular/src/lib/directives/text-highlight/text-highlight.directive.ts index 10740b8e373..bbdc7c5806e 100644 --- a/projects/igniteui-angular/src/lib/directives/text-highlight/text-highlight.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/text-highlight/text-highlight.directive.ts @@ -13,14 +13,7 @@ import { import { takeUntil } from 'rxjs/operators'; import { Subject } from 'rxjs'; import { compareMaps } from '../../core/utils'; - -interface ISearchInfo { - searchedText: string; - content: string; - matchCount: number; - caseSensitive: boolean; - exactMatch: boolean; -} +import { ISearchInfo } from '../../grids/common/events'; /** * An interface describing information for the active highlight. @@ -274,11 +267,12 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke } this._lastSearchInfo = { - searchedText: '', + searchText: '', content: this.value, matchCount: 0, caseSensitive: false, - exactMatch: false + exactMatch: false, + activeMatchIndex: 0 }; this._container = this.parentElement.firstElementChild; @@ -289,7 +283,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke */ public ngAfterViewChecked() { if (this._valueChanged) { - this.highlight(this._lastSearchInfo.searchedText, this._lastSearchInfo.caseSensitive, this._lastSearchInfo.exactMatch); + this.highlight(this._lastSearchInfo.searchText, this._lastSearchInfo.caseSensitive, this._lastSearchInfo.exactMatch); this.activateIfNecessary(); this._valueChanged = false; } @@ -304,7 +298,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke const exactMatchResolved = exactMatch ? true : false; if (this.searchNeedsEvaluation(text, caseSensitiveResolved, exactMatchResolved)) { - this._lastSearchInfo.searchedText = text; + this._lastSearchInfo.searchText = text; this._lastSearchInfo.caseSensitive = caseSensitiveResolved; this._lastSearchInfo.exactMatch = exactMatchResolved; this._lastSearchInfo.content = this.value; @@ -316,7 +310,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke this._lastSearchInfo.matchCount = this.getHighlightedText(text, caseSensitive, exactMatch); } } else if (this._nodeWasRemoved) { - this._lastSearchInfo.searchedText = text; + this._lastSearchInfo.searchText = text; this._lastSearchInfo.caseSensitive = caseSensitiveResolved; this._lastSearchInfo.exactMatch = exactMatchResolved; } @@ -330,7 +324,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke public clearHighlight(): void { this.clearChildElements(false); - this._lastSearchInfo.searchedText = ''; + this._lastSearchInfo.searchText = ''; this._lastSearchInfo.matchCount = 0; } @@ -368,7 +362,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke this._nodeWasRemoved = false; this._forceEvaluation = true; - this.highlight(this._lastSearchInfo.searchedText, + this.highlight(this._lastSearchInfo.searchText, this._lastSearchInfo.caseSensitive, this._lastSearchInfo.exactMatch); this._forceEvaluation = false; @@ -492,7 +486,7 @@ export class IgxTextHighlightDirective implements AfterViewInit, AfterViewChecke } private searchNeedsEvaluation(text: string, caseSensitive: boolean, exactMatch: boolean): boolean { - const searchedText = this._lastSearchInfo.searchedText; + const searchedText = this._lastSearchInfo.searchText; return !this._nodeWasRemoved && (searchedText === null || diff --git a/projects/igniteui-angular/src/lib/grids/cell.component.ts b/projects/igniteui-angular/src/lib/grids/cell.component.ts index 27743e15e12..fdab07cbc3c 100644 --- a/projects/igniteui-angular/src/lib/grids/cell.component.ts +++ b/projects/igniteui-angular/src/lib/grids/cell.component.ts @@ -929,7 +929,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy, CellT } if (changes.value && !changes.value.firstChange) { if (this.highlight) { - this.highlight.lastSearchInfo.searchedText = this.grid.lastSearchInfo.searchText; + this.highlight.lastSearchInfo.searchText = this.grid.lastSearchInfo.searchText; this.highlight.lastSearchInfo.caseSensitive = this.grid.lastSearchInfo.caseSensitive; this.highlight.lastSearchInfo.exactMatch = this.grid.lastSearchInfo.exactMatch; } diff --git a/projects/igniteui-angular/src/lib/grids/common/events.ts b/projects/igniteui-angular/src/lib/grids/common/events.ts index b2dfc121d88..ff92cec1f39 100644 --- a/projects/igniteui-angular/src/lib/grids/common/events.ts +++ b/projects/igniteui-angular/src/lib/grids/common/events.ts @@ -103,7 +103,15 @@ export interface ISearchInfo { caseSensitive: boolean; exactMatch: boolean; activeMatchIndex: number; - matchInfoCache: any[]; + matchCount: number; + content: string; +} + +export interface IMatchInfoCache { + row: any; + index: number; + column: string; + metadata: Map; } export interface IGridToolbarExportEventArgs extends IBaseEventArgs { diff --git a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts index 29b7a07f207..41b8eb895c3 100644 --- a/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts +++ b/projects/igniteui-angular/src/lib/grids/grid-base.directive.ts @@ -120,7 +120,8 @@ import { IFilteringEventArgs, IColumnVisibilityChangedEventArgs, IColumnVisibilityChangingEventArgs, - IPinColumnCancellableEventArgs + IPinColumnCancellableEventArgs, + IMatchInfoCache } from './common/events'; import { IgxAdvancedFilteringDialogComponent } from './filtering/advanced-filtering/advanced-filtering-dialog.component'; import { @@ -2826,14 +2827,15 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements public disableTransitions = false; /** - * @hidden @internal + * Represents the last search information. */ public lastSearchInfo: ISearchInfo = { searchText: '', caseSensitive: false, exactMatch: false, activeMatchIndex: 0, - matchInfoCache: [] + matchCount: 0, + content: '' }; /** @@ -3112,6 +3114,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements private _sortHeaderIconTemplate: TemplateRef = null; private _sortAscendingHeaderIconTemplate: TemplateRef = null; private _sortDescendingHeaderIconTemplate: TemplateRef = null; + private _matchInfoCache: IMatchInfoCache[] = []; /** * @hidden @internal @@ -5047,7 +5050,7 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements if (updateActiveInfo) { const activeInfo = IgxTextHighlightDirective.highlightGroupsMap.get(this.id); - this.lastSearchInfo.matchInfoCache.forEach((match, i) => { + this._matchInfoCache.forEach((match, i) => { if (match.column === activeInfo.column && match.row === activeInfo.row && match.index === activeInfo.index && @@ -5082,7 +5085,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements caseSensitive: false, exactMatch: false, activeMatchIndex: 0, - matchInfoCache: [] + matchCount: 0, + content: '' }; this.rowList.forEach((row) => { @@ -7485,7 +7489,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements activeMatchIndex: 0, caseSensitive: caseSensitiveResolved, exactMatch: exactMatchResolved, - matchInfoCache: [] + matchCount: 0, + content: '' }; rebuildCache = true; @@ -7505,14 +7510,14 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements this.rebuildMatchCache(); } - if (this.lastSearchInfo.activeMatchIndex >= this.lastSearchInfo.matchInfoCache.length) { + if (this.lastSearchInfo.activeMatchIndex >= this.lastSearchInfo.matchCount) { this.lastSearchInfo.activeMatchIndex = 0; } else if (this.lastSearchInfo.activeMatchIndex < 0) { - this.lastSearchInfo.activeMatchIndex = this.lastSearchInfo.matchInfoCache.length - 1; + this.lastSearchInfo.activeMatchIndex = this.lastSearchInfo.matchCount - 1; } - if (this.lastSearchInfo.matchInfoCache.length) { - const matchInfo = this.lastSearchInfo.matchInfoCache[this.lastSearchInfo.activeMatchIndex]; + if (this.lastSearchInfo.matchCount > 0) { + const matchInfo = this._matchInfoCache[this.lastSearchInfo.activeMatchIndex]; this.lastSearchInfo = { ...this.lastSearchInfo }; if (scroll !== false) { @@ -7530,17 +7535,18 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements IgxTextHighlightDirective.clearActiveHighlight(this.id); } - return this.lastSearchInfo.matchInfoCache.length; + return this.lastSearchInfo.matchCount; } private rebuildMatchCache() { - this.lastSearchInfo.matchInfoCache = []; + this._matchInfoCache = []; const caseSensitive = this.lastSearchInfo.caseSensitive; const exactMatch = this.lastSearchInfo.exactMatch; const searchText = caseSensitive ? this.lastSearchInfo.searchText : this.lastSearchInfo.searchText.toLowerCase(); const data = this.filteredSortedData; const columnItems = this.visibleColumns.filter((c) => !c.columnGroup).sort((c1, c2) => c1.visibleIndex - c2.visibleIndex); + data.forEach((dataRow, rowIndex) => { columnItems.forEach((c) => { const pipeArgs = this.getColumnByName(c.field).pipeArgs; @@ -7554,28 +7560,28 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements if (exactMatch) { if (searchValue === searchText) { - const metadata = new Map(); - metadata.set('pinned', this.isRecordPinnedByIndex(rowIndex)); - this.lastSearchInfo.matchInfoCache.push({ + const mic: IMatchInfoCache = { row: dataRow, column: c.field, index: 0, - metadata, - }); + metadata: new Map([['pinned', this.isRecordPinnedByIndex(rowIndex)]]) + }; + + this._matchInfoCache.push(mic); } } else { - let occurenceIndex = 0; + let occurrenceIndex = 0; let searchIndex = searchValue.indexOf(searchText); while (searchIndex !== -1) { - const metadata = new Map(); - metadata.set('pinned', this.isRecordPinnedByIndex(rowIndex)); - this.lastSearchInfo.matchInfoCache.push({ + const mic: IMatchInfoCache = { row: dataRow, column: c.field, - index: occurenceIndex++, - metadata, - }); + index: occurrenceIndex++, + metadata: new Map([['pinned', this.isRecordPinnedByIndex(rowIndex)]]) + }; + + this._matchInfoCache.push(mic); searchValue = searchValue.substring(searchIndex + searchText.length); searchIndex = searchValue.indexOf(searchText); @@ -7584,6 +7590,8 @@ export abstract class IgxGridBaseDirective extends DisplayDensityBase implements } }); }); + + this.lastSearchInfo.matchCount = this._matchInfoCache.length; } // TODO: About to Move to CRUD diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid.search.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid.search.spec.ts index e966324031e..0cdbd5c31f6 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid.search.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid.search.spec.ts @@ -395,7 +395,7 @@ describe('IgxGrid - search API #grid', () => { let highlights = getHighlights(); expect(highlights.length).toBe(3); verifyActiveHighlight(0); - expect(grid.lastSearchInfo.matchInfoCache.length).toBe(3); + expect(grid.lastSearchInfo.matchCount).toBe(3); expect(grid.lastSearchInfo.activeMatchIndex).toBe(0); grid.columnList.get(1).hidden = true; @@ -403,7 +403,7 @@ describe('IgxGrid - search API #grid', () => { highlights = getHighlights(); expect(highlights.length).toBe(1); verifyActiveHighlight(0); - expect(grid.lastSearchInfo.matchInfoCache.length).toBe(1); + expect(grid.lastSearchInfo.matchCount).toBe(1); expect(grid.lastSearchInfo.activeMatchIndex).toBe(0); }); diff --git a/src/app/grid-search-box/grid-search-box.component.html b/src/app/grid-search-box/grid-search-box.component.html index b2ced7e9607..53f2e081dd5 100644 --- a/src/app/grid-search-box/grid-search-box.component.html +++ b/src/app/grid-search-box/grid-search-box.component.html @@ -10,10 +10,10 @@
- - {{ grid.lastSearchInfo.activeMatchIndex + 1 }}/{{ grid.lastSearchInfo.matchInfoCache.length }} + + {{ grid.lastSearchInfo.activeMatchIndex + 1 }}/{{ grid.lastSearchInfo.matchCount }} - + 0/0