From a39b7b4f8721e46671d34d34bb608f82faa23708 Mon Sep 17 00:00:00 2001 From: Ivan Kitanov Date: Fri, 4 Jul 2025 10:42:13 +0300 Subject: [PATCH 1/4] fix(grid): Preventing rangeSelection from element inside cellTemplate --- .../grids/grid/grid-cell-selection.spec.ts | 23 +++++++++++++++++-- .../lib/grids/selection/selection.service.ts | 5 ++-- .../src/lib/test-utils/grid-samples.spec.ts | 20 ++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts index 9c7501966b3..07d0014609f 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts @@ -5,7 +5,8 @@ import { SelectionWithScrollsComponent, SelectionWithTransactionsComponent, CellSelectionNoneComponent, - CellSelectionSingleComponent + CellSelectionSingleComponent, + IgxGridCellTemplateForRangeSelectionComponent } from '../../test-utils/grid-samples.spec'; import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition'; import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec'; @@ -26,7 +27,8 @@ describe('IgxGrid - Cell selection #grid', () => { SelectionWithScrollsComponent, SelectionWithTransactionsComponent, CellSelectionNoneComponent, - CellSelectionSingleComponent + CellSelectionSingleComponent, + IgxGridCellTemplateForRangeSelectionComponent ] }).compileComponents(); })); @@ -256,6 +258,23 @@ describe('IgxGrid - Cell selection #grid', () => { expect(grid.selectedCells.length).toBe(1); }); + it('Should not trigger range selection when CellTemplate is used and the user clicks on element inside it',()=>{ + fix = TestBed.createComponent(IgxGridCellTemplateForRangeSelectionComponent); + fix.detectChanges(); + grid = fix.componentInstance.grid; + detect = () => grid.cdr.detectChanges(); + + const selectionChangeSpy = spyOn(grid.rangeSelected, 'emit').and.callThrough(); + const cell = grid.gridAPI.get_cell_by_index(1, 'ProductID'); + const cellElement = cell.nativeElement; + const span = cellElement.querySelector('span'); + + expect(span).not.toBeNull(); + span.click(); + fix.detectChanges(); + expect(selectionChangeSpy).not.toHaveBeenCalled(); + }); + it('Should be able to select range when click on a cell and hold Shift key and click on another Cell', () => { const firstCell = grid.gridAPI.get_cell_by_index(3, 'HireDate'); const secondCell = grid.gridAPI.get_cell_by_index(1, 'ID'); diff --git a/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts b/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts index 83287824d16..49b0e4f54f9 100644 --- a/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts +++ b/projects/igniteui-angular/src/lib/grids/selection/selection.service.ts @@ -637,7 +637,7 @@ export class IgxGridSelectionService { if (this.areEqualCollections(currSelection, newSelection)) { return; } - + const args: IRowSelectionEventArgs = { owner: this.grid, oldSelection: currSelection, @@ -857,8 +857,7 @@ export class IgxGridSelectionService { this.pointerEventInGridBody = false; this.grid.document.body.removeEventListener('pointerup', this.pointerOriginHandler); - const targetTagName = event.target.tagName.toLowerCase(); - if (targetTagName !== 'igx-grid-cell' && targetTagName !== 'igx-tree-grid-cell') { + if (!event.target.closest('igx-grid-cell') && !event.target.closest('igx-tree-grid-cell')) { this.pointerUp(this._lastSelectedNode, this.grid.rangeSelected, true); } }; diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts index 784f63e9965..af14e961aec 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts @@ -1414,6 +1414,26 @@ export class IgxGridRowEditingWithoutEditableColumnsComponent extends BasicGridC public override data = SampleTestData.foodProductData(); } +@Component({ + template: ` + + + + val +
+ {{val}} +
+
+ + + +
`, + imports: [IgxGridComponent, IgxColumnComponent, IgxCellTemplateDirective] +}) +export class IgxGridCellTemplateForRangeSelectionComponent extends BasicGridComponent { + public override data = SampleTestData.foodProductData(); +} + @Component({ template: ` From 8cdf9ea796e1c10194e06d999c3b52be62408d6b Mon Sep 17 00:00:00 2001 From: Ivan Kitanov Date: Wed, 23 Jul 2025 17:18:55 +0300 Subject: [PATCH 2/4] chore(grid): Unifying test sample and updating test --- .../grids/grid/grid-cell-selection.spec.ts | 22 +++++++++++---- .../src/lib/test-utils/grid-samples.spec.ts | 27 +++++-------------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts index 07d0014609f..43e06736a17 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts @@ -6,7 +6,7 @@ import { SelectionWithTransactionsComponent, CellSelectionNoneComponent, CellSelectionSingleComponent, - IgxGridCellTemplateForRangeSelectionComponent + IgxGridRowEditingWithoutEditableColumnsComponent } from '../../test-utils/grid-samples.spec'; import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition'; import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec'; @@ -28,7 +28,7 @@ describe('IgxGrid - Cell selection #grid', () => { SelectionWithTransactionsComponent, CellSelectionNoneComponent, CellSelectionSingleComponent, - IgxGridCellTemplateForRangeSelectionComponent + IgxGridRowEditingWithoutEditableColumnsComponent ] }).compileComponents(); })); @@ -259,10 +259,17 @@ describe('IgxGrid - Cell selection #grid', () => { }); it('Should not trigger range selection when CellTemplate is used and the user clicks on element inside it',()=>{ - fix = TestBed.createComponent(IgxGridCellTemplateForRangeSelectionComponent); + fix = TestBed.createComponent(IgxGridRowEditingWithoutEditableColumnsComponent); fix.detectChanges(); + + const component = fix.componentInstance; grid = fix.componentInstance.grid; - detect = () => grid.cdr.detectChanges(); + + expect(component.customCell).toBeDefined(); + + const column = grid.getColumnByName('ProductID'); + column.bodyTemplate = component.customCell; + fix.detectChanges(); const selectionChangeSpy = spyOn(grid.rangeSelected, 'emit').and.callThrough(); const cell = grid.gridAPI.get_cell_by_index(1, 'ProductID'); @@ -270,7 +277,12 @@ describe('IgxGrid - Cell selection #grid', () => { const span = cellElement.querySelector('span'); expect(span).not.toBeNull(); - span.click(); + + + const pointerDown = new PointerEvent('pointerdown', { bubbles: true }); + const pointerUp = new PointerEvent('pointerup', { bubbles: true }); + span.dispatchEvent(pointerDown); + span.dispatchEvent(pointerUp); fix.detectChanges(); expect(selectionChangeSpy).not.toHaveBeenCalled(); }); diff --git a/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts b/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts index af14e961aec..7c29ba15f5d 100644 --- a/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts +++ b/projects/igniteui-angular/src/lib/test-utils/grid-samples.spec.ts @@ -1407,31 +1407,18 @@ export class IgxGridRowEditingComponent extends BasicGridComponent { + + val +
+ {{val}} +
`, imports: [IgxGridComponent, IgxColumnComponent, IgxCellTemplateDirective] }) export class IgxGridRowEditingWithoutEditableColumnsComponent extends BasicGridComponent { public override data = SampleTestData.foodProductData(); -} - -@Component({ - template: ` - - - - val -
- {{val}} -
-
- - - -
`, - imports: [IgxGridComponent, IgxColumnComponent, IgxCellTemplateDirective] -}) -export class IgxGridCellTemplateForRangeSelectionComponent extends BasicGridComponent { - public override data = SampleTestData.foodProductData(); + @ViewChild('customCell', { static: true }) + public customCell!: TemplateRef; } @Component({ From 6b70efe4e65ad51ae43d36e178c49cef69fe01ac Mon Sep 17 00:00:00 2001 From: Ivan Kitanov <69432826+IvanKitanov17@users.noreply.github.com> Date: Wed, 23 Jul 2025 17:27:48 +0300 Subject: [PATCH 3/4] chore(grid): Fixing formatting --- .../src/lib/grids/grid/grid-cell-selection.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts index 43e06736a17..1ceac0e6575 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts @@ -258,7 +258,7 @@ describe('IgxGrid - Cell selection #grid', () => { expect(grid.selectedCells.length).toBe(1); }); - it('Should not trigger range selection when CellTemplate is used and the user clicks on element inside it',()=>{ + it('Should not trigger range selection when CellTemplate is used and the user clicks on element inside it', () => { fix = TestBed.createComponent(IgxGridRowEditingWithoutEditableColumnsComponent); fix.detectChanges(); From 548f406dc4f515a06fe5bd7d68d00a0a4fb37666 Mon Sep 17 00:00:00 2001 From: Ivan Kitanov <69432826+IvanKitanov17@users.noreply.github.com> Date: Wed, 23 Jul 2025 17:57:17 +0300 Subject: [PATCH 4/4] chore(grid): Replacing dispatch event with UiInteractions --- .../src/lib/grids/grid/grid-cell-selection.spec.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts index 1ceac0e6575..ae2779d20e3 100644 --- a/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/grid/grid-cell-selection.spec.ts @@ -278,11 +278,7 @@ describe('IgxGrid - Cell selection #grid', () => { expect(span).not.toBeNull(); - - const pointerDown = new PointerEvent('pointerdown', { bubbles: true }); - const pointerUp = new PointerEvent('pointerup', { bubbles: true }); - span.dispatchEvent(pointerDown); - span.dispatchEvent(pointerUp); + UIInteractions.simulateClickAndSelectEvent(span); fix.detectChanges(); expect(selectionChangeSpy).not.toHaveBeenCalled(); });