diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts index c392bbf35d5..85bfacc9eb8 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.component.ts @@ -90,6 +90,12 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseCompone this.reflow(); } this.cdr.markForCheck(); + if (this.parent && (this.height === null || this.height.indexOf('%') !== -1)) { + // If the height will change based on how much data there is, recalculate sizes in igxForOf. + requestAnimationFrame(() => { + this.updateParentSizes(); + }); + } } /** @@ -644,11 +650,18 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseCompone private updateParentSizes() { let currGrid = this.parent; while (currGrid) { + const hadScrollbar = currGrid.hasVerticalSroll(); const virt = currGrid.verticalScrollContainer; virt.recalcUpdateSizes(); const offset = parseInt(virt.dc.instance._viewContainer.element.nativeElement.style.top, 10); const scr = virt.getVerticalScroll(); scr.scrollTop = virt.getScrollForIndex(virt.state.startIndex) - offset; + + if (hadScrollbar !== currGrid.hasVerticalSroll()) { + // If after recalculations the grid should show vertical scrollbar it should also reflow. + currGrid.reflow(); + } + currGrid = currGrid.parent; } } diff --git a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts index 3537cbd8d31..1205c2005b0 100644 --- a/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts +++ b/projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.virtualization.spec.ts @@ -8,6 +8,7 @@ import { IgxRowIslandComponent } from './row-island.component'; import { wait } from '../../test-utils/ui-interactions.spec'; import { FilteringExpressionsTree, FilteringLogic, IgxStringFilteringOperand } from 'igniteui-angular'; import { By } from '@angular/platform-browser'; +import { first, delay } from 'rxjs/operators'; describe('IgxHierarchicalGrid Virtualization', () => { configureTestSuite(); @@ -339,6 +340,74 @@ describe('IgxHierarchicalGrid Virtualization', () => { expect(childRowComponent.index).toBe(4); }); + it('should update scrollbar when expanding a row with data loaded after initial view initialization', async(done) => { + fixture.componentInstance.data = fixture.componentInstance.generateData(10, 0); + fixture.detectChanges(); + + fixture.componentInstance.rowIsland.onGridCreated.pipe(first(), delay(200)).subscribe( + async(args) => { + args.grid.data = fixture.componentInstance.generateData(10, 0); + await wait(200); + fixture.detectChanges(); + + expect(hierarchicalGrid.verticalScrollContainer.getVerticalScroll().children[0].offsetHeight).toEqual(1184); + done(); + } + ); + + + expect(hierarchicalGrid.verticalScrollContainer.getVerticalScroll().children[0].offsetHeight).toEqual(500); + + // expand 1st row + const row = hierarchicalGrid.dataRowList.toArray()[0]; + row.nativeElement.children[0].click(); + fixture.detectChanges(); + + expect(hierarchicalGrid.verticalScrollContainer.getVerticalScroll().children[0].offsetHeight).toEqual(550); + }); +}); + +describe('IgxHierarchicalGrid Virtualization Custom Scenarios', () => { + configureTestSuite(); + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ + IgxHierarchicalGridTestBaseComponent, + IgxHierarchicalGridNoScrollTestComponent + ], + imports: [ + NoopAnimationsModule, IgxHierarchicalGridModule] + }).compileComponents(); + })); + + it('should show scrollbar after expanding a row with data loaded after initial view initialization', async(done) => { + const fixture = TestBed.createComponent(IgxHierarchicalGridNoScrollTestComponent); + fixture.detectChanges(); + + const hierarchicalGrid = fixture.componentInstance.hgrid; + fixture.componentInstance.rowIsland.onGridCreated.pipe(first(), delay(200)).subscribe( + async(args) => { + args.grid.data = fixture.componentInstance.generateData(10, 0); + await wait(200); + fixture.detectChanges(); + + expect(hierarchicalGrid.verticalScrollContainer.getVerticalScroll().parentElement.hidden).toBeFalsy(); + expect(hierarchicalGrid.tbody.nativeElement.offsetWidth).toBeLessThan(initialBodyWidth); + done(); + } + ); + + const initialBodyWidth = hierarchicalGrid.tbody.nativeElement.offsetWidth; + expect(hierarchicalGrid.verticalScrollContainer.getVerticalScroll().parentElement.hidden).toBeTruthy(); + + // expand 1st row + const row = hierarchicalGrid.dataRowList.toArray()[0]; + row.nativeElement.children[0].click(); + fixture.detectChanges(); + + expect(hierarchicalGrid.verticalScrollContainer.getVerticalScroll().parentElement.hidden).toBeTruthy(); + expect(hierarchicalGrid.tbody.nativeElement.offsetWidth).toEqual(initialBodyWidth); + }); }); @Component({ @@ -377,3 +446,20 @@ export class IgxHierarchicalGridTestBaseComponent { return prods; } } + +@Component({ + template: ` + + + + + + ` +}) +export class IgxHierarchicalGridNoScrollTestComponent extends IgxHierarchicalGridTestBaseComponent { + constructor() { + super(); + this.data = this.generateData(3, 0); + } +}