Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { IgxColumnComponent, } from 'igniteui-angular/grids/core';
import { IgxHierarchicalGridNavigationService } from './hierarchical-grid-navigation.service';
import { IgxGridSummaryService } from 'igniteui-angular/grids/core';
import { IgxHierarchicalGridBaseDirective } from './hierarchical-grid-base.directive';
import { takeUntil } from 'rxjs/operators';
import { first, takeUntil } from 'rxjs/operators';
import { CellType, GridType, IGX_GRID_BASE, IGX_GRID_SERVICE_BASE, RowType } from 'igniteui-angular/grids/core';
import { IgxRowIslandAPIService } from './row-island-api.service';
import { IgxGridCRUDService } from 'igniteui-angular/grids/core';
Expand Down Expand Up @@ -1115,6 +1115,7 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
/** @hidden @internal **/
public onContainerScroll() {
this.hideOverlays();
this.updateChildRowEditingOverlayStateOnScroll();
}

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

/** @hidden @internal **/
protected override verticalScrollHandler(event) {
super.verticalScrollHandler(event);

this.zone.onStable.pipe(first()).subscribe(() => {
this.updateChildRowEditingOverlayStateOnScroll();
});
}

protected override generateDataFields(data: any[]): string[] {
return super.generateDataFields(data).filter((field) => {
const layoutsList = this.parentIsland ? this.parentIsland.children : this.childLayoutList;
Expand Down Expand Up @@ -1295,4 +1305,29 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseDirecti
childEntities: childEntities
}
}

private updateChildRowEditingOverlayStateOnScroll() {
const visibleArea = this.tbodyContainer.nativeElement.getBoundingClientRect();
const childGrids = this.gridAPI.getChildGrids(true) as IgxHierarchicalGridComponent[];

childGrids.forEach((grid) => {
const row = grid.crudService.rowInEditMode;

if (!grid.rowEditable || !grid.rowEditingOverlay || grid.rowEditingOverlay.collapsed) {
return;
}

if (!row || !this.isElementInVisibleArea(row.nativeElement, visibleArea)) {
grid.toggleRowEditingOverlay(false);
} else {
grid.toggleRowEditingOverlay(true);
grid.repositionRowEditingOverlay(row);
}
});
}
Comment thread
georgianastasov marked this conversation as resolved.
Outdated

private isElementInVisibleArea(element: HTMLElement, visibleArea: DOMRect) {
const rect = element.getBoundingClientRect();
return rect.bottom > visibleArea.top && rect.top < visibleArea.bottom;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,73 @@ describe('Basic IgxHierarchicalGrid #hGrid', () => {
expect(childGrids[1].height).toBe('200px');
});

it('should hide child row editing overlay when parent scroll moves child row out of view', () => {
Comment thread
georgianastasov marked this conversation as resolved.
hierarchicalGrid.getRowByIndex(0).expanded = true;
fixture.detectChanges();

const childGrid = hierarchicalGrid.gridAPI.getChildGrids()[0] as IgxHierarchicalGridComponent;
childGrid.primaryKey = 'ID';
childGrid.rowEditable = true;
fixture.detectChanges();

const row = childGrid.gridAPI.get_row_by_index(0);
spyOnProperty(childGrid.crudService, 'rowInEditMode', 'get').and.returnValue(row);
spyOnProperty(childGrid.rowEditingOverlay, 'collapsed', 'get').and.returnValue(false);
childGrid.rowEditingOverlay.element.style.display = 'block';

spyOn((hierarchicalGrid as any).tbodyContainer.nativeElement, 'getBoundingClientRect').and.returnValue({
top: 0,
bottom: 200
} as DOMRect);
let childRowRect = {
top: 40,
bottom: 80
} as DOMRect;
spyOn(row.nativeElement, 'getBoundingClientRect').and.callFake(() => childRowRect);
const repositionOverlaySpy = spyOn(childGrid, 'repositionRowEditingOverlay');
const toggleOverlaySpy = spyOn(childGrid, 'toggleRowEditingOverlay').and.callThrough();

const scroll = hierarchicalGrid.verticalScrollContainer.getScroll();
scroll.scrollTop = 10;
(hierarchicalGrid as any).verticalScrollHandler({ target: scroll });
(hierarchicalGrid as any).zone.onStable.emit(null);
fixture.detectChanges();

expect(repositionOverlaySpy).toHaveBeenCalledWith(row);
expect(toggleOverlaySpy).not.toHaveBeenCalledWith(false);
expect(childGrid.rowEditingOverlay.element.style.display).not.toBe('none');

repositionOverlaySpy.calls.reset();
toggleOverlaySpy.calls.reset();
childRowRect = {
top: -80,
bottom: -40
} as DOMRect;
scroll.scrollTop = 1000;
(hierarchicalGrid as any).verticalScrollHandler({ target: scroll });
(hierarchicalGrid as any).zone.onStable.emit(null);
fixture.detectChanges();

expect(repositionOverlaySpy).not.toHaveBeenCalled();
expect(toggleOverlaySpy).toHaveBeenCalledWith(false);
expect(childGrid.rowEditingOverlay.element.style.display).toBe('none');

repositionOverlaySpy.calls.reset();
toggleOverlaySpy.calls.reset();
childRowRect = {
top: 40,
bottom: 80
} as DOMRect;
scroll.scrollTop = 10;
(hierarchicalGrid as any).verticalScrollHandler({ target: scroll });
(hierarchicalGrid as any).zone.onStable.emit(null);
fixture.detectChanges();

expect(toggleOverlaySpy).toHaveBeenCalledWith(true);
expect(repositionOverlaySpy).toHaveBeenCalledWith(row);
expect(childGrid.rowEditingOverlay.element.style.display).not.toBe('none');
});

it('Should apply runtime option changes to all related child grids (both existing and not yet initialized).', () => {
const row = hierarchicalGrid.gridAPI.get_row_by_index(0) as IgxHierarchicalRowComponent;
UIInteractions.simulateClickAndSelectEvent(row.expander);
Expand Down
Loading