diff --git a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts index ed999ecad3b..61fd8075565 100644 --- a/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts +++ b/projects/igniteui-angular/grids/core/src/filtering/excel-style/excel-style-search.component.ts @@ -482,9 +482,17 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { const matchedData = cloneHierarchicalArray(this.esf.listData, 'children'); this.displayedListData = this.hierarchicalSelectMatches(matchedData, searchVal); this.cdr.detectChanges(); + /** + * There are two calls of `matchesNumericValue` in this method: one when we generate the displayedListData in hierarchicalSelectMatches method + * and another one when going through the tree nodes. We can avoid the second call by storing the items in a set. + * However, if the datasource is small there is no significant difference in performance but we would be adding extra memory overhead. + * We should test this when https://github.com/IgniteUI/igniteui-angular/issues/17144 issue is fixed with 100k or 1m records + */ this.tree.nodes.forEach(n => { n.selected = true; - if ((n.data as FilterListItem).label.toString().toLowerCase().indexOf(searchVal) > -1) { + const item = n.data as FilterListItem; + if (item.label.toString().toLowerCase().indexOf(searchVal) > -1 || + this.matchesNumericValue(item, searchVal)) { this.expandAllParentNodes(n); } }); @@ -492,7 +500,8 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { this.displayedListData = this.esf.listData.filter((it, i) => (i === 0 && it.isSpecial) || (it.label !== null && it.label !== undefined) && !it.isBlanks && - it.label.toString().toLowerCase().indexOf(searchVal) > -1); + (it.label.toString().toLowerCase().indexOf(searchVal) > -1 || + this.matchesNumericValue(it, searchVal))); this.esf.listData.forEach(i => i.isSelected = false); this.displayedListData.forEach(i => i.isSelected = true); @@ -724,7 +733,8 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { node.expanded = false; } - if (element.label.toString().toLowerCase().indexOf(searchVal) > -1) { + if (element.label.toString().toLowerCase().indexOf(searchVal) > -1 || + this.matchesNumericValue(element, searchVal)) { element.isSelected = true; this.hierarchicalSelectAllChildren(element); this._hierarchicalSelectedItems.push(element); @@ -802,6 +812,23 @@ export class IgxExcelStyleSearchComponent implements AfterViewInit, OnDestroy { } } + private matchesNumericValue(item: FilterListItem, searchVal: string): boolean { + const columnDataType = this.esf.column?.dataType; + if (typeof item.value !== 'number' || + (columnDataType !== GridColumnDataType.Number && + columnDataType !== GridColumnDataType.Currency && + columnDataType !== GridColumnDataType.Percent)) { + return false; + } + + let numericValue = item.value; + if (columnDataType === GridColumnDataType.Percent) { + numericValue = parseFloat((item.value * 100).toPrecision(15)); + } + + return numericValue.toString().toLowerCase().indexOf(searchVal) > -1; + } + private onArrowUpKeyDown() { if (this.focusedItem && this.focusedItem.index === 0 && this.virtDir.state.startIndex === 0) { // on ArrowUp the focus stays on the same element if it is the first focused diff --git a/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts b/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts index f53e72f788e..cf8e2ecbf43 100644 --- a/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts +++ b/projects/igniteui-angular/grids/grid/src/grid-filtering-ui.spec.ts @@ -4113,6 +4113,25 @@ describe('IgxGrid - Filtering actions - Excel style filtering #grid', () => { expect(listItems.length).toBe(8, 'incorrect rendered list items count'); }); + it('Should match numeric column values when searching without locale-specific formatting characters.', async () => { + GridFunctions.clickExcelFilterIconFromCodeAsync(fix, grid, 'Downloads'); + fix.detectChanges(); + await wait(100); + const searchComponent = GridFunctions.getExcelStyleSearchComponent(fix); + const inputNativeElement = GridFunctions.getExcelStyleSearchComponentInput(fix, searchComponent); + + // Type 1000 (without thousands separator) in search box. + // The value 1000 is displayed as "1,000" in the ESF list due to locale formatting. + // Searching "1000" should still match the "1,000" entry. + UIInteractions.clickAndSendInputElementValue(inputNativeElement, '1000', fix); + fix.detectChanges(); + await wait(100); + + const listItems = GridFunctions.getExcelStyleSearchComponentListItems(fix, searchComponent); + // Expect 3 items: Select All + Add to current filter + the matched "1,000" item + expect(listItems.length).toBe(3, 'searching plain number should match locale-formatted label'); + }); + it('Should enable/disable the apply button correctly.', async () => { GridFunctions.clickExcelFilterIconFromCodeAsync(fix, grid, 'ProductName'); fix.detectChanges(); diff --git a/src/app/grid-cellMerging/grid-cellMerging.component.html b/src/app/grid-cellMerging/grid-cellMerging.component.html index aa3b8ffe2c8..d5e33acb229 100644 --- a/src/app/grid-cellMerging/grid-cellMerging.component.html +++ b/src/app/grid-cellMerging/grid-cellMerging.component.html @@ -43,79 +43,84 @@

Grid with cell merge

} - - - - Value: {{val}},Index: {{cell.row.index}} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ + + + Value: {{val}},Index: {{cell.row.index}} + + + + + + + + + + + + + + + + + + + + + + + + -

Hierarchical grid with cell merge

+ + + + + + + + + +
- - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + -

Tree grid with cell merge

- - - - - - - - + + + + + + + + + + + + +
diff --git a/src/app/grid-cellMerging/grid-cellMerging.component.scss b/src/app/grid-cellMerging/grid-cellMerging.component.scss index 9f4f5d20867..43726e71150 100644 --- a/src/app/grid-cellMerging/grid-cellMerging.component.scss +++ b/src/app/grid-cellMerging/grid-cellMerging.component.scss @@ -20,3 +20,9 @@ .searchInput{ width: 800px; } + +.grids-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(800px, 1fr)); + gap: 1rem; +} diff --git a/src/app/grid-cellMerging/grid-cellMerging.component.ts b/src/app/grid-cellMerging/grid-cellMerging.component.ts index f3c18dd222c..de5ddba4e93 100644 --- a/src/app/grid-cellMerging/grid-cellMerging.component.ts +++ b/src/app/grid-cellMerging/grid-cellMerging.component.ts @@ -3,6 +3,7 @@ import { FormsModule } from '@angular/forms'; import { DefaultTreeGridMergeStrategy, IgxActionStripComponent, + IgxButtonDirective, IgxCellTemplateDirective, IgxColumnComponent, IgxGridComponent, @@ -12,10 +13,10 @@ import { IgxGridToolbarHidingComponent, IgxGridToolbarPinningComponent, IgxHierarchicalGridComponent, + IgxIconButtonDirective, IgxIconComponent, IgxInputDirective, IgxInputGroupComponent, - IgxPaginatorComponent, IgxPrefixDirective, IgxRowIslandComponent, IgxSuffixDirective, @@ -50,7 +51,9 @@ import { INVOICE_DATA } from '../shared/invoiceData'; IgxSuffixDirective, IgxIconComponent, IgxInputDirective, - IgxCellTemplateDirective + IgxCellTemplateDirective, + IgxButtonDirective, + IgxIconButtonDirective ] }) export class GridCellMergingComponent { diff --git a/src/app/grid-column-types/grid-column-types.sample.html b/src/app/grid-column-types/grid-column-types.sample.html index f086e6e8197..c13d6de97f1 100644 --- a/src/app/grid-column-types/grid-column-types.sample.html +++ b/src/app/grid-column-types/grid-column-types.sample.html @@ -9,7 +9,7 @@ [filterMode]="filterMode" rowSelection="multiple" [rowEditable]="false" - width="700px" + width="800px" [primaryKey]="'ID'"> @@ -45,7 +45,7 @@ [filterMode]="filterMode" rowSelection="multiple" [rowEditable]="true" - [width]="'700px'"> + [width]="'800px'"> diff --git a/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts b/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts index 0c9d4b1c08a..9111a5ac319 100644 --- a/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts +++ b/src/app/hierarchical-grid-remote/hierarchical-grid-remote.sample.ts @@ -55,9 +55,9 @@ export class HierarchicalGridRemoteSampleComponent implements OnInit, AfterViewI fields: [ { field: 'orderId', dataType: 'number' }, // first field will be treated as foreign key { field: 'productId', dataType: 'number' }, - { field: 'unitPrice', dataType: 'number' }, + { field: 'unitPrice', dataType: 'currency' }, { field: 'quantity', dataType: 'number' }, - { field: 'discount', dataType: 'number' } + { field: 'discount', dataType: 'percent' } ] } ] @@ -131,7 +131,7 @@ export class HierarchicalGridRemoteSampleComponent implements OnInit, AfterViewI console.log('data', data); event.grid.data = Object.values(data); event.grid.isLoading = false; - this.cdr.detectChanges(); + this.cdr.detectChanges(); }); } diff --git a/src/app/hierarchical-grid-updating/hierarchical-grid-updating.sample.html b/src/app/hierarchical-grid-updating/hierarchical-grid-updating.sample.html index 4012c2d5b4a..94a63a32bc8 100644 --- a/src/app/hierarchical-grid-updating/hierarchical-grid-updating.sample.html +++ b/src/app/hierarchical-grid-updating/hierarchical-grid-updating.sample.html @@ -4,29 +4,29 @@
- - - - - - - - - - - - - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/shared/sample-data.ts b/src/app/shared/sample-data.ts index cd368679619..3d4341715e0 100644 --- a/src/app/shared/sample-data.ts +++ b/src/app/shared/sample-data.ts @@ -15,6 +15,7 @@ export const SAMPLE_DATA = [ DateCreated: undefined, Contract: null, Time: new Date(2017, 10, 1, 11, 47, 0), + Discount: 0.05, }, { ID: 'ANATR', @@ -32,6 +33,7 @@ export const SAMPLE_DATA = [ DateCreated: new Date(2015, 10, 1, 11, 37, 22), Contract: true, Time: new Date(2017, 10, 1, 12, 17, 1), + Discount: 0.10, }, { ID: 'ANTON', @@ -47,7 +49,8 @@ export const SAMPLE_DATA = [ Fax: null, Employees: 16, DateCreated: new Date(2015, 10, 1, 11, 37, 23), - Contract: false + Contract: false, + Discount: 0.15, }, { ID: 'AROUT', @@ -65,6 +68,7 @@ export const SAMPLE_DATA = [ DateCreated: new Date(2010, 2, 15, 15, 51, 22), Contract: false, Time: new Date(2017, 11, 11, 11, 11, 1), + Discount: 0.20, }, { ID: 'BERGS', @@ -82,6 +86,7 @@ export const SAMPLE_DATA = [ DateCreated: new Date(2015, 2, 5, 5, 3, 22), Contract: true, Time: new Date(2018, 9, 14, 14, 4, 3), + Discount: 0.25, }, { ID: 'BLAUS', @@ -99,6 +104,7 @@ export const SAMPLE_DATA = [ DateCreated: new Date(2016, 7, 1, 19, 22, 22), Contract: true, Time: new Date(2018, 6, 7, 7, 6, 5), + Discount: 0.30, }, { ID: 'BLONP', @@ -115,7 +121,8 @@ export const SAMPLE_DATA = [ Employees: 34, DateCreated: new Date(2016, 10, 5, 21, 21, 22), Time: new Date(2018, 6, 17, 7, 6, 5), - Contract: true + Contract: true, + Discount: 0.05, }, { ID: 'BOLID', @@ -133,6 +140,7 @@ export const SAMPLE_DATA = [ DateCreated: new Date(2016, 4, 20), Contract: true, Time: new Date(2018, 6, 7, 7, 7, 7), + Discount: 0.10, }, { ID: 'BONAP', @@ -150,6 +158,7 @@ export const SAMPLE_DATA = [ DateCreated: new Date(2018, 3, 5, 8, 13, 22), Contract: false, Time: new Date(2018, 6, 7, 9, 19, 5), + Discount: 0.15, }, { ID: 'BOTTM', @@ -167,6 +176,7 @@ export const SAMPLE_DATA = [ DateCreated: new Date(2017, 6, 10, 7, 33, 22), Contract: true, Time: new Date(2018, 6, 7, 7, 6, 5), + Discount: 0.20, }, { ID: 'BSBEV', @@ -183,7 +193,8 @@ export const SAMPLE_DATA = [ Employees: 197, DateCreated: new Date(2017, 10, 4, 12, 42, 22), Contract: true, - Time: new Date(2021, 1, 2, 1, 12, 21) + Time: new Date(2021, 1, 2, 1, 12, 21), + Discount: 0.25, }, { ID: 'CACTU', @@ -199,7 +210,8 @@ export const SAMPLE_DATA = [ Fax: '(1) 135-4892', Employees: 33, DateCreated: new Date(2014, 5, 12, 11, 17, 22), - Contract: false + Contract: false, + Discount: 0.30, }, { ID: 'CENTC', @@ -215,7 +227,8 @@ export const SAMPLE_DATA = [ Fax: '(5) 555-7293', Employees: 18, DateCreated: new Date(2015, 6, 27, 6, 31, 22), - Contract: true + Contract: true, + Discount: 0.05, }, { ID: 'CHOPS', @@ -232,7 +245,8 @@ export const SAMPLE_DATA = [ Employees: 380, DateCreated: new Date(2011, 8, 6, 4, 11, 22), Contract: true, - Time: new Date(2023, 7, 12, 4, 42, 21) + Time: new Date(2023, 7, 12, 4, 42, 21), + Discount: 0.10, }, { ID: 'COMMI', @@ -247,7 +261,8 @@ export const SAMPLE_DATA = [ Fax: null, Employees: 137, DateCreated: new Date(2012, 6, 10, 16, 31, 22), - Contract: false + Contract: false, + Discount: 0.15, }, { ID: 'CONSH', @@ -264,7 +279,8 @@ export const SAMPLE_DATA = [ Employees: 150, DateCreated: new Date(2012, 6, 10, 5, 19, 22), Contract: false, - Time: new Date(2020, 9, 6, 14, 40, 20) + Time: new Date(2020, 9, 6, 14, 40, 20), + Discount: 0.20, }, { ID: 'DRACD', @@ -280,7 +296,8 @@ export const SAMPLE_DATA = [ Fax: '0241-059428', Employees: 265, DateCreated: new Date(2014, 9, 11, 3, 31, 22), - Contract: true + Contract: true, + Discount: 0.25, }, { ID: 'DUMON', @@ -297,7 +314,8 @@ export const SAMPLE_DATA = [ Employees: 24, DateCreated: new Date(2015, 8, 4, 5, 11, 22), Contract: true, - Time: new Date(2020, 9, 22, 16, 40, 10) + Time: new Date(2020, 9, 22, 16, 40, 10), + Discount: 0.30, }, { ID: 'EASTC', @@ -314,7 +332,8 @@ export const SAMPLE_DATA = [ Employees: 123, DateCreated: new Date(2013, 4, 18, 15, 39, 22), Contract: false, - Time: new Date(2020, 5, 4, 17, 30, 15) + Time: new Date(2020, 5, 4, 17, 30, 15), + Discount: 0.05, }, { ID: 'ERNSH', @@ -331,7 +350,8 @@ export const SAMPLE_DATA = [ Employees: 9, DateCreated: new Date(2013, 7, 9, 15, 31, 22), Contract: true, - Time: new Date(2020, 4, 7, 17, 30, 15) + Time: new Date(2020, 4, 7, 17, 30, 15), + Discount: 0.10, }, { ID: 'FAMIA', @@ -348,7 +368,8 @@ export const SAMPLE_DATA = [ Employees: 67, DateCreated: new Date(2015, 6, 17, 16, 22, 22), Contract: true, - Time: new Date(2020, 5, 17, 17, 45, 55) + Time: new Date(2020, 5, 17, 17, 45, 55), + Discount: 0.15, }, { ID: 'FISSA', @@ -365,7 +386,8 @@ export const SAMPLE_DATA = [ Employees: 87, DateCreated: new Date(2015, 6, 17, 14, 1, 22), Contract: false, - Time: new Date(2020, 3, 7, 15, 41, 27) + Time: new Date(2020, 3, 7, 15, 41, 27), + Discount: 0.20, }, { ID: 'FOLIG', @@ -382,7 +404,8 @@ export const SAMPLE_DATA = [ Employees: 37, DateCreated: new Date(2014, 5, 14, 15, 31, 22), Contract: false, - Time: new Date(2020, 8, 16, 16, 30, 15) + Time: new Date(2020, 8, 16, 16, 30, 15), + Discount: 0.25, }, { ID: 'FOLKO', @@ -399,7 +422,8 @@ export const SAMPLE_DATA = [ Employees: 42, DateCreated: new Date(2011, 3, 21, 17, 11, 22), Contract: true, - Time: new Date(2020, 8, 17, 10, 30, 15) + Time: new Date(2020, 8, 17, 10, 30, 15), + Discount: 0.30, }, { ID: 'FRANK', @@ -416,7 +440,8 @@ export const SAMPLE_DATA = [ Employees: 17, DateCreated: new Date(2015, 6, 17, 14, 41, 22), Contract: true, - Time: new Date(2020, 8, 7, 14, 14, 19) + Time: new Date(2020, 8, 7, 14, 14, 19), + Discount: 0.05, }, { ID: 'FRANR', @@ -433,7 +458,8 @@ export const SAMPLE_DATA = [ Employees: 20, DateCreated: new Date(2011, 7, 14, 15, 21, 22), Contract: true, - Time: new Date(2020, 6, 7, 20, 14, 15) + Time: new Date(2020, 6, 7, 20, 14, 15), + Discount: 0.10, }, { ID: 'FRANS', @@ -449,7 +475,8 @@ export const SAMPLE_DATA = [ Employees: 5, DateCreated: new Date(2012, 8, 3, 16, 31, 22), Contract: false, - Time: new Date(2020, 6, 7, 22, 4, 5) + Time: new Date(2020, 6, 7, 22, 4, 5), + Discount: 0.15, } ];