Skip to content

Preventing range selection from triggering when element inside CellTemplate is clicked - 20.0.x #16025

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

Merged
merged 10 commits into from
Jul 25, 2025
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
SelectionWithScrollsComponent,
SelectionWithTransactionsComponent,
CellSelectionNoneComponent,
CellSelectionSingleComponent
CellSelectionSingleComponent,
IgxGridRowEditingWithoutEditableColumnsComponent
} from '../../test-utils/grid-samples.spec';
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
import { UIInteractions, wait } from '../../test-utils/ui-interactions.spec';
Expand All @@ -26,7 +27,8 @@ describe('IgxGrid - Cell selection #grid', () => {
SelectionWithScrollsComponent,
SelectionWithTransactionsComponent,
CellSelectionNoneComponent,
CellSelectionSingleComponent
CellSelectionSingleComponent,
IgxGridRowEditingWithoutEditableColumnsComponent
]
}).compileComponents();
}));
Expand Down Expand Up @@ -256,6 +258,31 @@ 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(IgxGridRowEditingWithoutEditableColumnsComponent);
fix.detectChanges();

const component = fix.componentInstance;
grid = fix.componentInstance.grid;

expect(component.customCell).toBeDefined();

const column = grid.getColumnByName('ProductID');
column.bodyTemplate = component.customCell;
fix.detectChanges();

const selectionChangeSpy = spyOn<any>(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();

UIInteractions.simulateClickAndSelectEvent(span);
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');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
IgxHierarchicalGridRowSelectionComponent,
IgxHierarchicalGridRowSelectionTestSelectRowOnClickComponent,
IgxHierarchicalGridCustomSelectorsComponent,
IgxHierarchicalGridRowSelectionNoTransactionsComponent
IgxHierarchicalGridRowSelectionNoTransactionsComponent,
IgxHierGridExternalAdvancedFilteringComponent
} from '../../test-utils/hierarchical-grid-components.spec';
import { GridSelectionFunctions, GridFunctions } from '../../test-utils/grid-functions.spec';
import { GridSelectionMode, Size } from '../common/enums';
Expand All @@ -33,7 +34,8 @@ describe('IgxHierarchicalGrid selection #hGrid', () => {
IgxHierarchicalGridRowSelectionComponent,
IgxHierarchicalGridRowSelectionTestSelectRowOnClickComponent,
IgxHierarchicalGridCustomSelectorsComponent,
IgxHierarchicalGridRowSelectionNoTransactionsComponent
IgxHierarchicalGridRowSelectionNoTransactionsComponent,
IgxHierGridExternalAdvancedFilteringComponent,
]
}).compileComponents();
}))
Expand Down Expand Up @@ -474,6 +476,30 @@ describe('IgxHierarchicalGrid selection #hGrid', () => {
GridSelectionFunctions.verifySelectedRange(hierarchicalGrid, 0, 0, 2, 2);
}));

it('Should not trigger range selection when CellTemplate is used and the user clicks on element inside it', () => {
fix = TestBed.createComponent(IgxHierGridExternalAdvancedFilteringComponent);
fix.detectChanges();

const component = fix.componentInstance;
hierarchicalGrid = fix.componentInstance.hgrid;

expect(component.customCell).toBeDefined();

const column = hierarchicalGrid.getColumnByName('ID');
column.bodyTemplate = component.customCell;
fix.detectChanges();

const selectionChangeSpy = spyOn<any>(hierarchicalGrid.rangeSelected, 'emit').and.callThrough();
const cell = hierarchicalGrid.gridAPI.get_cell_by_index(0, 'ID');
const cellElement = cell.nativeElement;
const span = cellElement.querySelector('span');

expect(span).not.toBeNull();

UIInteractions.simulateClickAndSelectEvent(span);
fix.detectChanges();
expect(selectionChangeSpy).not.toHaveBeenCalled();
});
});

describe('Row Selection', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ export class IgxGridSelectionService {
if (this.areEqualCollections(currSelection, newSelection)) {
return;
}

const args: IRowSelectionEventArgs = {
owner: this.grid,
oldSelection: currSelection,
Expand Down Expand Up @@ -857,8 +857,10 @@ 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') {
const gridCellSelectors = ['igx-grid-cell', 'igx-hierarchical-grid-cell', 'igx-tree-grid-cell'];
const isInsideGridCell = gridCellSelectors.some(selector => event.target.closest(selector));

if (!isInsideGridCell) {
this.pointerUp(this._lastSelectedNode, this.grid.rangeSelected, true);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,27 @@ describe('IgxTreeGrid - Selection #tGrid', () => {
expect(treeGrid.selectedCells[0] instanceof IgxGridCell).toBe(true);
expect(treeGrid.selectedCells[0].value).toBe(19);
});

it('Should not trigger range selection when CellTemplate is used and the user clicks on element inside it', () => {
const component = fix.componentInstance;

expect(component.customCell).toBeDefined();

const column = treeGrid.getColumnByName('ID');
column.bodyTemplate = component.customCell;
fix.detectChanges();

const selectionChangeSpy = spyOn<any>(treeGrid.rangeSelected, 'emit').and.callThrough();
const cell = treeGrid.gridAPI.get_cell_by_index(0, 'ID');
const cellElement = cell.nativeElement;
const span = cellElement.querySelector('span');

expect(span).not.toBeNull();

UIInteractions.simulateClickAndSelectEvent(span);
fix.detectChanges();
expect(selectionChangeSpy).not.toHaveBeenCalled();
});
});

describe('Cell/Row Selection With Row Editing', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1407,11 +1407,18 @@ export class IgxGridRowEditingComponent extends BasicGridComponent {
<igx-column field="ReorderLevel" header="Reorder Lever" [dataType]="'number'" [editable]="true" width="100px"></igx-column>
<igx-column field="ProductName" header="Product Name" [dataType]="'string'" width="150px"></igx-column>
<igx-column field="OrderDate" header="Order Date" [dataType]="'date'" width="150px" [editable]="false"></igx-column>
<ng-template #customCell igxCell let-cell="cell" let-val>
<span style="background-color: red;">val</span>
<br>
{{val}}
</ng-template>
</igx-grid>`,
imports: [IgxGridComponent, IgxColumnComponent, IgxCellTemplateDirective]
})
export class IgxGridRowEditingWithoutEditableColumnsComponent extends BasicGridComponent {
public override data = SampleTestData.foodProductData();
@ViewChild('customCell', { static: true })
public customCell!: TemplateRef<any>;
}

@Component({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, ViewChild, OnInit } from '@angular/core';
import { Component, ViewChild, OnInit, TemplateRef } from '@angular/core';
import { SampleTestData } from './sample-test-data.spec';
import { ColumnType, IPinningConfig, IgxAdvancedFilteringDialogComponent, IgxColumnComponent, IgxNumberSummaryOperand, IgxSummaryResult } from '../grids/public_api';
import { IgxHierarchicalGridComponent } from '../grids/hierarchical-grid/hierarchical-grid.component';
Expand Down Expand Up @@ -460,6 +460,11 @@ export class IgxHierarchicalGridActionStripComponent extends IgxHierarchicalGrid
<igx-column field="ProductName"></igx-column>
</igx-row-island>
</igx-row-island>
<ng-template #customCell igxCell let-cell="cell" let-val>
<span style="background-color: red;">val</span>
<br>
{{val}}
</ng-template>
</igx-hierarchical-grid>
<igx-advanced-filtering-dialog [grid]="hierarchicalGrid">
</igx-advanced-filtering-dialog>`,
Expand All @@ -468,7 +473,8 @@ export class IgxHierarchicalGridActionStripComponent extends IgxHierarchicalGrid
export class IgxHierGridExternalAdvancedFilteringComponent extends IgxHierarchicalGridTestBaseComponent {
@ViewChild('hierarchicalGrid', { read: IgxHierarchicalGridComponent, static: true })
public override hgrid: IgxHierarchicalGridComponent;

@ViewChild('customCell', { static: true })
public customCell!: TemplateRef<any>;
public override data = SampleTestData.generateHGridData(5, 3);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, ViewChild, OnInit } from '@angular/core';
import { Component, ViewChild, OnInit, TemplateRef } from '@angular/core';
import { IgxTreeGridComponent } from '../grids/tree-grid/tree-grid.component';
import { SampleTestData } from './sample-test-data.spec';
import { IgxSummaryOperand, IgxNumberSummaryOperand, IgxSummaryResult, IPinningConfig, IgxColumnComponent } from '../grids/public_api';
Expand Down Expand Up @@ -191,13 +191,20 @@ export class IgxTreeGridExpandingComponent {
<igx-column [field]="'HireDate'" dataType="date"></igx-column>
<igx-column [field]="'Age'" dataType="number"></igx-column>
<igx-paginator [perPage]="10"></igx-paginator>
<ng-template #customCell igxCell let-cell="cell" let-val>
<span style="background-color: red;">val</span>
<br>
{{val}}
</ng-template>
</igx-tree-grid>
`,
imports: [IgxTreeGridComponent, IgxColumnComponent, IgxPaginatorComponent]
})
export class IgxTreeGridCellSelectionComponent {
@ViewChild(IgxTreeGridComponent, { static: true }) public treeGrid: IgxTreeGridComponent;
public data = SampleTestData.employeeTreeData();
@ViewChild('customCell', { static: true })
public customCell!: TemplateRef<any>;
}

@Component({
Expand Down
Loading