Skip to content

Commit 3b62c86

Browse files
authored
Merge branch '7.2.x' into dpetev/ios-grid-edit-7-2
2 parents 7eebad0 + 8238465 commit 3b62c86

File tree

3 files changed

+93
-53
lines changed

3 files changed

+93
-53
lines changed

projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid-navigation.service.ts

Lines changed: 58 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,17 @@ export class IgxHierarchicalGridNavigationService extends IgxGridNavigationServi
128128
public navigateTop(visibleColumnIndex) {
129129
if (this.grid.parent !== null) {
130130
// navigating in child
131-
const verticalScroll = this.grid.verticalScrollContainer.getVerticalScroll();
132-
const cellSelector = this.getCellSelector(visibleColumnIndex);
133-
134-
if (verticalScroll.scrollTop === 0) {
135-
this._focusScrollCellInView(visibleColumnIndex);
131+
const childContainer = this.grid.nativeElement.parentNode.parentNode;
132+
const diff =
133+
childContainer.getBoundingClientRect().top - this.grid.rootGrid.tbody.nativeElement.getBoundingClientRect().top;
134+
const topIsVisible = diff >= 0;
135+
const scrollable = this.getNextScrollable(this.grid);
136+
if (!topIsVisible) {
137+
this.scrollGrid(scrollable.grid, diff,
138+
() => super.navigateTop(visibleColumnIndex));
136139
} else {
137-
this.scrollGrid(this.grid, 'top',
138-
() => {
139-
const cells = this.grid.nativeElement.querySelectorAll(
140-
`${cellSelector}[data-visibleIndex="${visibleColumnIndex}"]`);
141-
if (cells.length > 0) {
142-
this._focusScrollCellInView(visibleColumnIndex);
143-
}
144-
});
140+
super.navigateTop(visibleColumnIndex);
145141
}
146-
147142
} else {
148143
super.navigateTop(visibleColumnIndex);
149144
}
@@ -289,27 +284,13 @@ export class IgxHierarchicalGridNavigationService extends IgxGridNavigationServi
289284
} else {
290285
this.focusNextChildDOMElem(currentRowEl, this.grid);
291286
}
287+
} else if (this.grid.parent && this.grid.parent.summariesRowList.length > 0) {
288+
this._navigateToNextParentRow(currentRowEl);
292289
} else {
293290
this.navigateDown(currentRowEl, rowIndex, 0);
294291
}
295292
} else if (isLastSummaryRow && isLastColumn && this.grid.parent) {
296-
// navigating in child summary, next is parent summary or next parent row
297-
const parent = this.grid.parent;
298-
const parentHasSummary = parent.summariesRowList.toArray().length > 0;
299-
const parentRowIndex = parseInt(
300-
this.getClosestElemByTag(currentRowEl, 'igx-child-grid-row').parentNode.getAttribute('data-rowindex'), 10);
301-
const isLastRowInParent = parent.verticalScrollContainer.igxForOf.length - 1 === parentRowIndex;
302-
// check if next is sibling
303-
const childRowContainer = this.getChildGridRowContainer(this.grid);
304-
const nextIsSiblingChild = !!childRowContainer.nextElementSibling;
305-
if (isLastRowInParent && parentHasSummary && !nextIsSiblingChild) {
306-
// next is parent summary
307-
const parentSummary = parent.summariesRowList.toArray()[0].nativeElement;
308-
parent.navigation.focusNextRow(parentSummary, 0, this.grid.rootGrid, true);
309-
} else {
310-
// next is sibling or parent
311-
this.focusNext(0);
312-
}
293+
this._navigateToNextParentRow(currentRowEl);
313294
} else if (isLastDataRow && hasSummaries && isLastColumn && this.grid.parent) {
314295
// navigating in child rows, next is child grid's summary row
315296
this.focusNextRow(summaryRows[0].nativeElement, 0, this.grid.parent, true);
@@ -318,6 +299,26 @@ export class IgxHierarchicalGridNavigationService extends IgxGridNavigationServi
318299
}
319300
}
320301

302+
private _navigateToNextParentRow(currentRowEl: any): void {
303+
// next is parent summary or next parent row
304+
const parent = this.grid.parent;
305+
const parentHasSummary = parent.summariesRowList.length > 0;
306+
const parentRowIndex = parseInt(
307+
this.getClosestElemByTag(currentRowEl, 'igx-child-grid-row').parentNode.getAttribute('data-rowindex'), 10);
308+
const isLastRowInParent = parent.verticalScrollContainer.igxForOf.length - 1 === parentRowIndex;
309+
// check if next is sibling
310+
const childRowContainer = this.getChildGridRowContainer(this.grid);
311+
const nextIsSiblingChild = !!childRowContainer.nextElementSibling;
312+
if (isLastRowInParent && parentHasSummary && !nextIsSiblingChild) {
313+
// next is parent summary
314+
const parentSummary = parent.summariesRowList.first.nativeElement;
315+
parent.navigation.focusNextRow(parentSummary, 0, parent, true);
316+
} else {
317+
// next is sibling or parent
318+
this.focusNext(0);
319+
}
320+
}
321+
321322
private focusNextChildDOMElem(currentRowEl, grid) {
322323
const gridElem = currentRowEl.nextElementSibling.querySelector('igx-hierarchical-grid');
323324
const childGridID = gridElem.getAttribute('id');
@@ -442,31 +443,27 @@ export class IgxHierarchicalGridNavigationService extends IgxGridNavigationServi
442443
childGrid.allowFiltering && childGrid.filterMode === FilterMode.quickFilter) {
443444
// move to filter cell
444445
childGrid.navigation.moveFocusToFilterCell();
446+
} else if (childGrid.rowList.length === 0) {
447+
// move to prev child or parent row
448+
const prevChild = this.getSibling(childGrid);
449+
if (prevChild) {
450+
this.performShiftTabIntoChild(prevChild, currentRowEl, rowIndex);
451+
} else {
452+
this.navigateUp(currentRowEl, rowIndex,
453+
this.grid.unpinnedColumns[this.grid.unpinnedColumns.length - 1].visibleIndex);
454+
}
445455
} else {
446-
// move to next cell
447-
this.navigateUp(currentRowEl, rowIndex, lastIndex);
456+
// move to prev cell
457+
childGrid.navigation.goToLastCell();
448458
}
449459
}
450460

451-
private _focusScrollCellInView(visibleColumnIndex) {
452-
const cellSelector = this.getCellSelector(visibleColumnIndex);
453-
const cells = this.grid.nativeElement.querySelectorAll(
454-
`${cellSelector}[data-visibleIndex="${visibleColumnIndex}"]`);
455-
const cell = cells[0];
456-
const childContainer = this.grid.nativeElement.parentNode.parentNode;
457-
const scrTop = this.grid.parent.verticalScrollContainer.getVerticalScroll().scrollTop;
458-
const maxScroll = this.grid.parent.verticalScrollContainer.getVerticalScroll().scrollHeight - this.grid.parent.calcHeight;
459-
const dc = childContainer.parentNode.parentNode;
460-
const scrWith = parseInt(dc.style.top, 10);
461-
const parentRowOffset = childContainer.parentNode.offsetTop + this.grid.nativeElement.offsetTop +
462-
scrWith;
463-
if ((scrTop === 0 && parentRowOffset < 0 ) || parentRowOffset === 0 || (scrTop === maxScroll && parentRowOffset > 0)) {
464-
// cell is in view
465-
cell.focus({preventScroll: true});
466-
} else {
467-
// scroll parent so that cell is in view
468-
this.scrollGrid(this.grid.parent, parentRowOffset, () => cell.focus({ preventScroll: true }));
461+
private getSibling(childGrid) {
462+
const prevChildRow = childGrid.childRow.nativeElement.previousElementSibling;
463+
if (prevChildRow) {
464+
return prevChildRow.children[0].children[0];
469465
}
466+
return null;
470467
}
471468

472469
private focusNextChild(elem, visibleColumnIndex, grid) {
@@ -590,14 +587,17 @@ export class IgxHierarchicalGridNavigationService extends IgxGridNavigationServi
590587
const nextIsSiblingChild = !!childRowContainer.nextElementSibling;
591588
let next = childRowContainer.nextElementSibling || nextParentElem;
592589
const verticalScroll = nextParentGrid.verticalScrollContainer.getVerticalScroll();
590+
const parentState = nextParentGrid.verticalScrollContainer.state;
591+
const atLastChunk = parentState.startIndex + parentState.chunkSize ===
592+
nextParentGrid.verticalScrollContainer.igxForOf.length;
593593
if (next) {
594594
if (nextIsSiblingChild) {
595595
this.focusNextChild(next, visibleColumnIndex, nextParentGrid);
596596
} else {
597597
this.focusNextRow(next, visibleColumnIndex, grid || nextParentGrid);
598598
}
599599
} else if (verticalScroll.scrollTop !==
600-
verticalScroll.scrollHeight - nextParentGrid.verticalScrollContainer.igxForContainerSize ) {
600+
verticalScroll.scrollHeight - nextParentGrid.verticalScrollContainer.igxForContainerSize && !atLastChunk) {
601601
this.scrollGrid(nextParentGrid, 'next',
602602
() => {
603603
nextParentElem = parentInfo.nextElement;
@@ -717,7 +717,12 @@ export class IgxHierarchicalGridNavigationService extends IgxGridNavigationServi
717717
grid.parentVirtDir.onChunkLoad
718718
.pipe(first())
719719
.subscribe(callBackFunc);
720-
grid.dataRowList.toArray()[0].virtDirRow.scrollTo(unpinnedIndex);
720+
if (grid.dataRowList.length > 0) {
721+
grid.dataRowList.first.virtDirRow.scrollTo(unpinnedIndex);
722+
} else {
723+
grid.headerContainer.scrollTo(unpinnedIndex);
724+
}
725+
721726
}
722727
private scrollGrid(grid, target, callBackFunc) {
723728
this.getFocusableGrid().nativeElement.focus({preventScroll: true});

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,11 +365,17 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseCompone
365365
this._displayDensity = this.rootGrid._displayDensity;
366366
if (document.body.contains(this.nativeElement)) {
367367
this.reflow();
368+
this.cdr.detectChanges();
368369
} else {
369370
this.updateOnRender = true;
370371
}
371372
});
372373
});
374+
this.parent.verticalScrollContainer.onDataChanged.pipe(takeUntil(this.destroy$)).subscribe(() => {
375+
requestAnimationFrame(() => {
376+
this.updateSizes();
377+
});
378+
});
373379
this.childLayoutKeys = this.parentIsland.children.map((item) => item.key);
374380
} else {
375381
this.childLayoutKeys = this.childLayoutList.map((item) => item.key);
@@ -381,6 +387,16 @@ export class IgxHierarchicalGridComponent extends IgxHierarchicalGridBaseCompone
381387
this.toolbarCustomContentTemplates;
382388
}
383389

390+
private updateSizes() {
391+
if (!this._destroyed && document.body.contains(this.nativeElement) && this.isPercentWidth) {
392+
this.reflow();
393+
394+
this.hgridAPI.getChildGrids(false).forEach((grid) => {
395+
grid.updateSizes();
396+
});
397+
}
398+
}
399+
384400
public get outletDirective() {
385401
return this.rootGrid._outletDirective;
386402
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { IgxHierarchicalRowComponent } from './hierarchical-row.component';
1010
import { By } from '@angular/platform-browser';
1111
import { IgxChildGridRowComponent } from './child-grid-row.component';
1212
import { DisplayDensity } from '../../core/displayDensity';
13+
import { IgxStringFilteringOperand } from '../../data-operations/filtering-condition';
1314

1415
describe('Basic IgxHierarchicalGrid', () => {
1516
configureTestSuite();
@@ -333,6 +334,24 @@ describe('Basic IgxHierarchicalGrid', () => {
333334
fixture.detectChanges();
334335
expect(childGrid.calcWidth - 170).toBeLessThan(3);
335336
});
337+
338+
it('child grid width should be recalculated if parent no longer shows scrollbar.', async () => {
339+
hierarchicalGrid.height = '1000px';
340+
fixture.detectChanges();
341+
hierarchicalGrid.filter('ProductName', 'A0', IgxStringFilteringOperand.instance().condition('contains'), true);
342+
fixture.detectChanges();
343+
const row = hierarchicalGrid.getRowByIndex(0) as IgxHierarchicalRowComponent;
344+
UIInteractions.clickElement(row.expander);
345+
const childGrids = fixture.debugElement.queryAll(By.css('igx-child-grid-row'));
346+
const childGrid = childGrids[0].query(By.css('igx-hierarchical-grid')).componentInstance;
347+
expect(childGrid.calcWidth - 370 - childGrid.scrollWidth).toBeLessThanOrEqual(5);
348+
349+
hierarchicalGrid.clearFilter();
350+
fixture.detectChanges();
351+
await wait(30);
352+
353+
expect(childGrid.calcWidth - 370 ).toBeLessThan(3);
354+
});
336355
});
337356

338357
describe('IgxHierarchicalGrid Row Islands', () => {

0 commit comments

Comments
 (0)