Skip to content

Commit 1fea5cc

Browse files
authored
Merge pull request #9771 from IgniteUI/hanastasov/viewIndex-fix-m
Calculate viewIndex properly for each type of row
2 parents 8918370 + 73e8597 commit 1fea5cc

File tree

8 files changed

+337
-43
lines changed

8 files changed

+337
-43
lines changed

projects/igniteui-angular/src/lib/grids/common/row.interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { GridType } from './grid.interface';
55

66
export interface RowType {
77
index: number;
8-
viewIndex?: number;
8+
viewIndex: number;
99
isGroupByRow?: boolean;
1010
isSummaryRow?: boolean;
1111
summaries?: Map<string, IgxSummaryResult[]>;

projects/igniteui-angular/src/lib/grids/grid-public-row.ts

Lines changed: 197 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { DeprecateProperty } from '../core/deprecateDecorators';
22
import { IGroupByRecord } from '../data-operations/groupby-record.interface';
33
import { IgxRow } from './common/crud.service';
4+
import { GridSummaryCalculationMode, GridSummaryPosition } from './common/enums';
45
import { RowType } from './common/row.interface';
56
import { IgxGridAPIService } from './grid/grid-api.service';
67
import { IgxGridComponent } from './grid/grid.component';
@@ -17,6 +18,13 @@ abstract class BaseRow implements RowType {
1718
public grid: IgxGridComponent | IgxTreeGridComponent | IgxHierarchicalGridComponent;
1819
protected _data?: any;
1920

21+
/**
22+
* Returns the view index calculated per the grid page.
23+
*/
24+
public get viewIndex(): number {
25+
return this.index + this.grid.page * this.grid.perPage;
26+
}
27+
2028
/**
2129
* Gets the row key.
2230
* A row in the grid is identified either by:
@@ -63,13 +71,6 @@ abstract class BaseRow implements RowType {
6371
return this.key;
6472
}
6573

66-
/**
67-
* Returns the view index calculated per the grid page.
68-
*/
69-
public get viewIndex(): number {
70-
return this.index + this.grid.page * this.grid.perPage;
71-
}
72-
7374
/**
7475
* Returns if the row is currently in edit mode.
7576
*/
@@ -249,10 +250,45 @@ export class IgxGridRow extends BaseRow implements RowType {
249250
* Returns the view index calculated per the grid page.
250251
*/
251252
public get viewIndex(): number {
252-
if (this.grid.groupingExpressions.length) {
253-
return this.grid.filteredSortedData.indexOf(this.data);
254-
}
255-
return this.index + this.grid.page * this.grid.perPage;
253+
if (this.grid.page) {
254+
const precedingDetailRows = [];
255+
const precedingGroupRows = [];
256+
const firstRow = this.grid.dataView[0];
257+
const hasDetailRows = this.grid.expansionStates.size;
258+
const hasGroupedRows = this.grid.groupingExpressions.length;
259+
let precedingSummaryRows = 0;
260+
const firstRowInd = this.grid.groupingFlatResult.indexOf(firstRow);
261+
262+
// from groupingFlatResult, resolve two other collections:
263+
// precedingGroupedRows -> use it to resolve summaryRow for each group in previous pages
264+
// precedingDetailRows -> ise it to resolve the detail row for each expanded grid row in previous pages
265+
if (hasDetailRows || hasGroupedRows) {
266+
this.grid.groupingFlatResult.forEach((r, ind) => {
267+
const rowID = this.grid.primaryKey ? r[this.grid.primaryKey] : r;
268+
if (hasGroupedRows && ind < firstRowInd && this.grid.isGroupByRecord(r)) {
269+
precedingGroupRows.push(r);
270+
}
271+
if (this.grid.expansionStates.get(rowID) && ind < firstRowInd && !this.grid.isGroupByRecord(r)) {
272+
precedingDetailRows.push(r);
273+
}
274+
});
275+
}
276+
277+
if (this.grid.summaryCalculationMode !== GridSummaryCalculationMode.rootLevelOnly) {
278+
// if firstRow is a child of the last item in precedingGroupRows,
279+
// then summaryRow for this given groupedRecord is rendered after firstRow,
280+
// i.e. need to decrease firstRowInd to account for the above.
281+
precedingSummaryRows = precedingGroupRows.filter(gr => this.grid.isExpandedGroup(gr)).length;
282+
if (this.grid.summaryPosition === GridSummaryPosition.bottom && precedingGroupRows.length &&
283+
precedingGroupRows[precedingGroupRows.length - 1].records.indexOf(firstRow) > -1) {
284+
precedingSummaryRows += -1;
285+
}
286+
}
287+
288+
return precedingDetailRows.length + precedingSummaryRows + firstRowInd + this.index;
289+
} else {
290+
return this.index;
291+
}
256292
}
257293

258294
/**
@@ -285,6 +321,24 @@ export class IgxTreeGridRow extends BaseRow implements RowType {
285321
super();
286322
}
287323

324+
/**
325+
* Returns the view index calculated per the grid page.
326+
*/
327+
public get viewIndex(): number {
328+
if (this.grid.hasSummarizedColumns && this.grid.page > 0) {
329+
if (this.grid.summaryCalculationMode !== GridSummaryCalculationMode.rootLevelOnly) {
330+
const firstRowIndex = this.grid.processedExpandedFlatData.indexOf(this.grid.dataView[0].data);
331+
// firstRowIndex is based on data result after all pipes triggered, excluding summary pipe
332+
const precedingSummaryRows = this.grid.summaryPosition === GridSummaryPosition.bottom ?
333+
this.grid.rootRecords.indexOf(this.getRootParent(this.grid.dataView[0])) :
334+
this.grid.rootRecords.indexOf(this.getRootParent(this.grid.dataView[0])) + 1;
335+
// there is a summary row for each root record, so we calculate how many root records are rendered before the current row
336+
return firstRowIndex + precedingSummaryRows + this.index;
337+
}
338+
}
339+
return this.index + this.grid.page * this.grid.perPage;
340+
}
341+
288342
/**
289343
* The data passed to the row component.
290344
*
@@ -319,7 +373,7 @@ export class IgxTreeGridRow extends BaseRow implements RowType {
319373
* Returns the parent row.
320374
*/
321375
public get parent(): RowType {
322-
const row = this.grid.getRowByKey(this.treeRow.parent.rowID);
376+
const row = this.grid.getRowByKey(this.treeRow.parent?.rowID);
323377
return row;
324378
}
325379

@@ -392,16 +446,16 @@ export class IgxTreeGridRow extends BaseRow implements RowType {
392446
public set expanded(val: boolean) {
393447
this.grid.gridAPI.set_row_expansion_state(this.key, val);
394448
}
395-
}
396449

397-
export class IgxHierarchicalGridRow extends BaseRow implements RowType {
398-
/**
399-
* Returns the view index calculated per the grid page.
400-
*/
401-
public get viewIndex(): number {
402-
return this.index + this.grid.page * this.grid.perPage;
450+
private getRootParent(row: ITreeGridRecord): ITreeGridRecord {
451+
while (row.parent) {
452+
row = row.parent;
453+
}
454+
return row;
403455
}
456+
}
404457

458+
export class IgxHierarchicalGridRow extends BaseRow implements RowType {
405459
/**
406460
* @hidden
407461
*/
@@ -416,6 +470,15 @@ export class IgxHierarchicalGridRow extends BaseRow implements RowType {
416470
public get hasChildren(): boolean {
417471
return !!this.grid.childLayoutKeys.length;
418472
}
473+
474+
public get viewIndex() {
475+
const firstRowInd = this.grid.filteredSortedData.indexOf(this.grid.dataView[0]);
476+
const expandedRows = this.grid.filteredSortedData.filter((rec, ind) => {
477+
const rowID = this.grid.primaryKey ? rec[this.grid.primaryKey] : rec;
478+
return this.grid.expansionStates.get(rowID) && ind < firstRowInd;
479+
});
480+
return firstRowInd + expandedRows.length + this.index;
481+
}
419482
}
420483

421484
export class IgxGroupByRow implements RowType {
@@ -453,10 +516,55 @@ export class IgxGroupByRow implements RowType {
453516
return children;
454517
}
455518

519+
/**
520+
* Returns the view index calculated per the grid page.
521+
*/
522+
public get viewIndex(): number {
523+
if (this.grid.page) {
524+
const precedingDetailRows = [];
525+
const precedingGroupRows = [];
526+
const firstRow = this.grid.dataView[0];
527+
const hasDetailRows = this.grid.expansionStates.size;
528+
const hasGroupedRows = this.grid.groupingExpressions.length;
529+
let precedingSummaryRows = 0;
530+
const firstRowInd = this.grid.groupingFlatResult.indexOf(firstRow);
531+
532+
// from groupingFlatResult, resolve two other collections:
533+
// precedingGroupedRows -> use it to resolve summaryRow for each group in previous pages
534+
// precedingDetailRows -> ise it to resolve the detail row for each expanded grid row in previous pages
535+
if (hasDetailRows || hasGroupedRows) {
536+
this.grid.groupingFlatResult.forEach((r, ind) => {
537+
const rowID = this.grid.primaryKey ? r[this.grid.primaryKey] : r;
538+
if (hasGroupedRows && ind < firstRowInd && this.grid.isGroupByRecord(r)) {
539+
precedingGroupRows.push(r);
540+
}
541+
if (this.grid.expansionStates.get(rowID) && ind < firstRowInd && !this.grid.isGroupByRecord(r)) {
542+
precedingDetailRows.push(r);
543+
}
544+
});
545+
}
546+
547+
if (this.grid.summaryCalculationMode !== GridSummaryCalculationMode.rootLevelOnly) {
548+
// if firstRow is a child of the last item in precedingGroupRows,
549+
// then summaryRow for this given groupedRecord is rendered after firstRow,
550+
// i.e. need to decrease firstRowInd to account for the above.
551+
precedingSummaryRows = precedingGroupRows.filter(gr => this.grid.isExpandedGroup(gr)).length;
552+
if (this.grid.summaryPosition === GridSummaryPosition.bottom && precedingGroupRows.length &&
553+
precedingGroupRows[precedingGroupRows.length - 1].records.indexOf(firstRow) > -1) {
554+
precedingSummaryRows += -1;
555+
}
556+
}
557+
558+
return precedingDetailRows.length + precedingSummaryRows + firstRowInd + this.index;
559+
} else {
560+
return this.index;
561+
}
562+
}
563+
456564
/**
457565
* @hidden
458566
*/
459-
constructor(grid: IgxGridComponent, index: number, private _groupRow?: IGroupByRecord) {
567+
constructor(grid: IgxGridComponent, index: number, private _groupRow?: IGroupByRecord) {
460568
this.grid = grid;
461569
this.index = index;
462570
this.isGroupByRow = true;
@@ -549,6 +657,68 @@ export class IgxSummaryRow implements RowType {
549657
return this._summaries ? this._summaries : this.grid.dataView[this.index].summaries;
550658
}
551659

660+
/**
661+
* Returns the view index calculated per the grid page.
662+
*/
663+
public get viewIndex(): number {
664+
if (this.grid.hasSummarizedColumns && this.grid.page > 0) {
665+
if (this.grid instanceof IgxGridComponent) {
666+
const grid = this.grid as IgxGridComponent;
667+
if (grid.page) {
668+
const precedingDetailRows = [];
669+
const precedingGroupRows = [];
670+
const firstRow = this.grid.dataView[0];
671+
const hasDetailRows = this.grid.expansionStates.size;
672+
const hasGroupedRows = this.grid.groupingExpressions.length;
673+
let precedingSummaryRows = 0;
674+
const firstRowInd = this.grid.groupingFlatResult.indexOf(firstRow);
675+
676+
// from groupingFlatResult, resolve two other collections:
677+
// precedingGroupedRows -> use it to resolve summaryRow for each group in previous pages
678+
// precedingDetailRows -> ise it to resolve the detail row for each expanded grid row in previous pages
679+
if (hasDetailRows || hasGroupedRows) {
680+
this.grid.groupingFlatResult.forEach((r, ind) => {
681+
const rowID = this.grid.primaryKey ? r[this.grid.primaryKey] : r;
682+
if (hasGroupedRows && ind < firstRowInd && this.grid.isGroupByRecord(r)) {
683+
precedingGroupRows.push(r);
684+
}
685+
if (this.grid.expansionStates.get(rowID) && ind < firstRowInd &&
686+
!this.grid.isGroupByRecord(r)) {
687+
precedingDetailRows.push(r);
688+
}
689+
});
690+
}
691+
692+
if (this.grid.summaryCalculationMode !== GridSummaryCalculationMode.rootLevelOnly) {
693+
// if firstRow is a child of the last item in precedingGroupRows,
694+
// then summaryRow for this given groupedRecord is rendered after firstRow,
695+
// i.e. need to decrease firstRowInd to account for the above.
696+
precedingSummaryRows = precedingGroupRows.filter(gr => this.grid.isExpandedGroup(gr)).length;
697+
if (this.grid.summaryPosition === GridSummaryPosition.bottom && precedingGroupRows.length &&
698+
precedingGroupRows[precedingGroupRows.length - 1].records.indexOf(firstRow) > -1) {
699+
precedingSummaryRows += -1;
700+
}
701+
}
702+
703+
return precedingDetailRows.length + precedingSummaryRows + firstRowInd + this.index;
704+
} else {
705+
return this.index;
706+
}
707+
} else if (this.grid instanceof IgxTreeGridComponent) {
708+
const grid = this.grid as IgxTreeGridComponent;
709+
if (grid.summaryCalculationMode !== GridSummaryCalculationMode.rootLevelOnly) {
710+
const firstRowIndex = grid.processedExpandedFlatData.indexOf(grid.dataView[0].data);
711+
const precedingSummaryRows = this.grid.summaryPosition === GridSummaryPosition.bottom ?
712+
this.grid.rootRecords.indexOf(this.getRootParent(grid.dataView[0])) :
713+
this.grid.rootRecords.indexOf(this.getRootParent(grid.dataView[0])) + 1;
714+
return firstRowIndex + precedingSummaryRows + this.index;
715+
}
716+
}
717+
}
718+
719+
return this.index + this.grid.page * this.grid.perPage;
720+
}
721+
552722
/**
553723
* @hidden
554724
*/
@@ -558,4 +728,11 @@ export class IgxSummaryRow implements RowType {
558728
this.index = index;
559729
this.isSummaryRow = true;
560730
}
731+
732+
private getRootParent(row: ITreeGridRecord): ITreeGridRecord {
733+
while (row.parent) {
734+
row = row.parent;
735+
}
736+
return row;
737+
}
561738
}

0 commit comments

Comments
 (0)