1
1
import { DeprecateProperty } from '../core/deprecateDecorators' ;
2
2
import { IGroupByRecord } from '../data-operations/groupby-record.interface' ;
3
3
import { IgxRow } from './common/crud.service' ;
4
+ import { GridSummaryCalculationMode , GridSummaryPosition } from './common/enums' ;
4
5
import { RowType } from './common/row.interface' ;
5
6
import { IgxGridAPIService } from './grid/grid-api.service' ;
6
7
import { IgxGridComponent } from './grid/grid.component' ;
@@ -17,6 +18,13 @@ abstract class BaseRow implements RowType {
17
18
public grid : IgxGridComponent | IgxTreeGridComponent | IgxHierarchicalGridComponent ;
18
19
protected _data ?: any ;
19
20
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
+
20
28
/**
21
29
* Gets the row key.
22
30
* A row in the grid is identified either by:
@@ -63,13 +71,6 @@ abstract class BaseRow implements RowType {
63
71
return this . key ;
64
72
}
65
73
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
-
73
74
/**
74
75
* Returns if the row is currently in edit mode.
75
76
*/
@@ -249,10 +250,45 @@ export class IgxGridRow extends BaseRow implements RowType {
249
250
* Returns the view index calculated per the grid page.
250
251
*/
251
252
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
+ }
256
292
}
257
293
258
294
/**
@@ -285,6 +321,24 @@ export class IgxTreeGridRow extends BaseRow implements RowType {
285
321
super ( ) ;
286
322
}
287
323
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
+
288
342
/**
289
343
* The data passed to the row component.
290
344
*
@@ -319,7 +373,7 @@ export class IgxTreeGridRow extends BaseRow implements RowType {
319
373
* Returns the parent row.
320
374
*/
321
375
public get parent ( ) : RowType {
322
- const row = this . grid . getRowByKey ( this . treeRow . parent . rowID ) ;
376
+ const row = this . grid . getRowByKey ( this . treeRow . parent ? .rowID ) ;
323
377
return row ;
324
378
}
325
379
@@ -392,16 +446,16 @@ export class IgxTreeGridRow extends BaseRow implements RowType {
392
446
public set expanded ( val : boolean ) {
393
447
this . grid . gridAPI . set_row_expansion_state ( this . key , val ) ;
394
448
}
395
- }
396
449
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 ;
403
455
}
456
+ }
404
457
458
+ export class IgxHierarchicalGridRow extends BaseRow implements RowType {
405
459
/**
406
460
* @hidden
407
461
*/
@@ -416,6 +470,15 @@ export class IgxHierarchicalGridRow extends BaseRow implements RowType {
416
470
public get hasChildren ( ) : boolean {
417
471
return ! ! this . grid . childLayoutKeys . length ;
418
472
}
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
+ }
419
482
}
420
483
421
484
export class IgxGroupByRow implements RowType {
@@ -453,10 +516,55 @@ export class IgxGroupByRow implements RowType {
453
516
return children ;
454
517
}
455
518
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
+
456
564
/**
457
565
* @hidden
458
566
*/
459
- constructor ( grid : IgxGridComponent , index : number , private _groupRow ?: IGroupByRecord ) {
567
+ constructor ( grid : IgxGridComponent , index : number , private _groupRow ?: IGroupByRecord ) {
460
568
this . grid = grid ;
461
569
this . index = index ;
462
570
this . isGroupByRow = true ;
@@ -549,6 +657,68 @@ export class IgxSummaryRow implements RowType {
549
657
return this . _summaries ? this . _summaries : this . grid . dataView [ this . index ] . summaries ;
550
658
}
551
659
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
+
552
722
/**
553
723
* @hidden
554
724
*/
@@ -558,4 +728,11 @@ export class IgxSummaryRow implements RowType {
558
728
this . index = index ;
559
729
this . isSummaryRow = true ;
560
730
}
731
+
732
+ private getRootParent ( row : ITreeGridRecord ) : ITreeGridRecord {
733
+ while ( row . parent ) {
734
+ row = row . parent ;
735
+ }
736
+ return row ;
737
+ }
561
738
}
0 commit comments