Skip to content

Commit 71bb96b

Browse files
fix(hierarchical-grid): hide child row editing overlay on scroll
1 parent e5e1f51 commit 71bb96b

2 files changed

Lines changed: 103 additions & 1 deletion

File tree

projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.component.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { IgxColumnComponent, } from 'igniteui-angular/grids/core';
88
import { IgxHierarchicalGridNavigationService } from './hierarchical-grid-navigation.service';
99
import { IgxGridSummaryService } from 'igniteui-angular/grids/core';
1010
import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.directive';
11-
import { takeUntil } from 'rxjs/operators';
11+
import { first, takeUntil } from 'rxjs/operators';
1212
import { CellType, GridType, IGX_GRID_BASE, IGX_GRID_SERVICE_BASE, RowType } from 'igniteui-angular/grids/core';
1313
import { IgxRowIslandAPIService } from './row-island-api.service';
1414
import { IgxGridCRUDService } from 'igniteui-angular/grids/core';
@@ -1115,6 +1115,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
11151115
/** @hidden @internal **/
11161116
public onContainerScroll() {
11171117
this.hideOverlays();
1118+
this.updateChildRowEditingOverlayStateOnScroll();
11181119
}
11191120

11201121
/**
@@ -1137,6 +1138,15 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
11371138
return this.gridAPI.getChildGrids(inDeph);
11381139
}
11391140

1141+
/** @hidden @internal **/
1142+
protected override verticalScrollHandler(event) {
1143+
super.verticalScrollHandler(event);
1144+
1145+
this.zone.onStable.pipe(first()).subscribe(() => {
1146+
this.updateChildRowEditingOverlayStateOnScroll();
1147+
});
1148+
}
1149+
11401150
protected override generateDataFields(data: any[]): string[] {
11411151
return super.generateDataFields(data).filter((field) => {
11421152
const layoutsList = this.parentIsland ? this.parentIsland.children : this.childLayoutList;
@@ -1295,4 +1305,29 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
12951305
childEntities: childEntities
12961306
}
12971307
}
1308+
1309+
private updateChildRowEditingOverlayStateOnScroll() {
1310+
const visibleArea = this.tbodyContainer.nativeElement.getBoundingClientRect();
1311+
const childGrids = this.gridAPI.getChildGrids(true) as IgxHierarchicalGridComponent[];
1312+
1313+
childGrids.forEach((grid) => {
1314+
const row = grid.crudService.rowInEditMode;
1315+
1316+
if (!grid.rowEditable || !grid.rowEditingOverlay || grid.rowEditingOverlay.collapsed) {
1317+
return;
1318+
}
1319+
1320+
if (!row || !this.isElementInVisibleArea(row.nativeElement, visibleArea)) {
1321+
grid.toggleRowEditingOverlay(false);
1322+
} else {
1323+
grid.toggleRowEditingOverlay(true);
1324+
grid.repositionRowEditingOverlay(row);
1325+
}
1326+
});
1327+
}
1328+
1329+
private isElementInVisibleArea(element: HTMLElement, visibleArea: DOMRect) {
1330+
const rect = element.getBoundingClientRect();
1331+
return rect.bottom > visibleArea.top && rect.top < visibleArea.bottom;
1332+
}
12981333
}

projects/igniteui-angular/grids/hierarchical-grid/src/hierarchical-grid.spec.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,73 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => {
783783
expect(childGrids[1].height).toBe('200px');
784784
});
785785

786+
it('should hide child row editing overlay when parent scroll moves child row out of view', () => {
787+
hierarchicalGrid.getRowByIndex(0).expanded = true;
788+
fixture.detectChanges();
789+
790+
const childGrid = hierarchicalGrid.gridAPI.getChildGrids()[0] as IgxHierarchicalGridComponent;
791+
childGrid.primaryKey = 'ID';
792+
childGrid.rowEditable = true;
793+
fixture.detectChanges();
794+
795+
const row = childGrid.gridAPI.get_row_by_index(0);
796+
spyOnProperty(childGrid.crudService, 'rowInEditMode', 'get').and.returnValue(row);
797+
spyOnProperty(childGrid.rowEditingOverlay, 'collapsed', 'get').and.returnValue(false);
798+
childGrid.rowEditingOverlay.element.style.display = 'block';
799+
800+
spyOn((hierarchicalGrid as any).tbodyContainer.nativeElement, 'getBoundingClientRect').and.returnValue({
801+
top: 0,
802+
bottom: 200
803+
} as DOMRect);
804+
let childRowRect = {
805+
top: 40,
806+
bottom: 80
807+
} as DOMRect;
808+
spyOn(row.nativeElement, 'getBoundingClientRect').and.callFake(() => childRowRect);
809+
const repositionOverlaySpy = spyOn(childGrid, 'repositionRowEditingOverlay');
810+
const toggleOverlaySpy = spyOn(childGrid, 'toggleRowEditingOverlay').and.callThrough();
811+
812+
const scroll = hierarchicalGrid.verticalScrollContainer.getScroll();
813+
scroll.scrollTop = 10;
814+
(hierarchicalGrid as any).verticalScrollHandler({ target: scroll });
815+
(hierarchicalGrid as any).zone.onStable.emit(null);
816+
fixture.detectChanges();
817+
818+
expect(repositionOverlaySpy).toHaveBeenCalledWith(row);
819+
expect(toggleOverlaySpy).not.toHaveBeenCalledWith(false);
820+
expect(childGrid.rowEditingOverlay.element.style.display).not.toBe('none');
821+
822+
repositionOverlaySpy.calls.reset();
823+
toggleOverlaySpy.calls.reset();
824+
childRowRect = {
825+
top: -80,
826+
bottom: -40
827+
} as DOMRect;
828+
scroll.scrollTop = 1000;
829+
(hierarchicalGrid as any).verticalScrollHandler({ target: scroll });
830+
(hierarchicalGrid as any).zone.onStable.emit(null);
831+
fixture.detectChanges();
832+
833+
expect(repositionOverlaySpy).not.toHaveBeenCalled();
834+
expect(toggleOverlaySpy).toHaveBeenCalledWith(false);
835+
expect(childGrid.rowEditingOverlay.element.style.display).toBe('none');
836+
837+
repositionOverlaySpy.calls.reset();
838+
toggleOverlaySpy.calls.reset();
839+
childRowRect = {
840+
top: 40,
841+
bottom: 80
842+
} as DOMRect;
843+
scroll.scrollTop = 10;
844+
(hierarchicalGrid as any).verticalScrollHandler({ target: scroll });
845+
(hierarchicalGrid as any).zone.onStable.emit(null);
846+
fixture.detectChanges();
847+
848+
expect(toggleOverlaySpy).toHaveBeenCalledWith(true);
849+
expect(repositionOverlaySpy).toHaveBeenCalledWith(row);
850+
expect(childGrid.rowEditingOverlay.element.style.display).not.toBe('none');
851+
});
852+
786853
it('Should apply runtime option changes to all related child grids (both existing and not yet initialized).', () => {
787854
const row = hierarchicalGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;
788855
UIInteractions.simulateClickAndSelectEvent(row.expander);

0 commit comments

Comments
 (0)