-
Notifications
You must be signed in to change notification settings - Fork 160
fix(grid): ESF search matches numeric values without locale formatting #17131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
acba841
38d8fb3
436df63
c194f75
f64877c
feae3bd
1f31b1f
21ad1b0
963abd4
004391d
3b29d85
9a1079a
8bc860d
a98950e
d01aa20
e5e2f3c
dd86e81
cfe2463
b2ce2c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -482,17 +482,26 @@ 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); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+824
to
+829
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let numericValue = item.value; | |
| if (columnDataType === GridColumnDataType.Percent) { | |
| numericValue = parseFloat((item.value * 100).toPrecision(15)); | |
| } | |
| return numericValue.toString().toLowerCase().indexOf(searchVal) > -1; | |
| // Normalize the search value: remove grouping separators, trim, and parse as number. | |
| const normalizedSearch = searchVal ? searchVal.replace(/,/g, '').trim() : ''; | |
| if (!normalizedSearch) { | |
| return false; | |
| } | |
| const parsedSearch = Number(normalizedSearch); | |
| if (Number.isNaN(parsedSearch)) { | |
| return false; | |
| } | |
| let numericValue = item.value; | |
| if (columnDataType === GridColumnDataType.Percent) { | |
| numericValue = parseFloat((item.value * 100).toPrecision(15)); | |
| } | |
| const canonicalItem = numericValue.toString(); | |
| const canonicalSearch = parsedSearch.toString(); | |
| return canonicalItem.toLowerCase().indexOf(canonicalSearch.toLowerCase()) > -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kdinev The only thing that comes to my mind regarding the performance is that
matchesNumericValueis called a second time here when the ESF is hierarchical. Firstly, it is called inside thehierarchicalSelectMatchesmethod when generatingdisplayedListDataand then when going through the tree nodes to expand parent nodes. What we can do is to create a set and populate it with the items and then match a record to the set so that we skip the second call. However, this is not a big deal sincematchesNumericValueis just parsing some numbers but can add up if the data is big.