get index of row in angular material table v5
Asked Answered
B

10

81

I'm trying to get the index of row in table, in html, which has been implemented using angular material v5.2. Is there any method available to get the index?

The code for reference:

<div class="example-container mat-elevation-z8">
  <div class="example-header">
    <mat-form-field>
      <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
    </mat-form-field>
  </div>

  <mat-table #table [dataSource]="dataSource">

    <!-- Position Column -->
    <ng-container matColumnDef="position">
      <mat-header-cell *matHeaderCellDef> No. </mat-header-cell>
      <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="name">
     <button (click)="doSomething()"> Do something</button>
    </ng-container>

    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </mat-table>
</div>

The method doSomething is what needs index.

Any help would be greatly appreciated.

Brainard answered 11/5, 2018 at 12:27 Comment(0)
A
161

Using indexOf is an enormous waste of resources. The right way is initializing a variable with index's value, like this:

<ng-container matColumnDef="position">
  <th mat-header-cell *matHeaderCellDef mat-sort-header> Num. </th>
  <td mat-cell *matCellDef="let element; let i = index">{{i + 1}}</td>
</ng-container>

https://material.angular.io/components/table/examples

UPDATE:

If you are using pagination the index can be calculated this way:

<ng-container matColumnDef="position">
  <th mat-header-cell *matHeaderCellDef mat-sort-header> Num. </th>
  <td mat-cell *matCellDef="let i = index">
  {{this.paginator.pageIndex == 0 ? i + 1 : 1 + i + this.paginator.pageIndex * this.paginator.pageSize}}
  </td>
</ng-container>
Aby answered 24/5, 2018 at 21:45 Comment(6)
This is the right way to do it. If you're not using the anything from your dataSource in this column (e.g. element), you don't need to declare it. You can just do <td mat-cell *matCellDef="let i = index">{{i}}</td>Bondsman
<td mat-cell *matCellDef="let element; let i = index">{{i}}</td> This WorksBags
One thing that baffles me is why on earth is half the answer in French?Anew
@Aby If we are using mat-paginator along with mat-table, how to accomplish the same ?Strachey
This is working You need to define paginator id we have used multiple paginations on the same HTML file <td mat-cell *matCellDef="let i = index;">{{ this.TableTwoPaginator.pageIndex == 0 ? i+1 : i+ 1 + this.TableTwoPaginator.pageIndex * this.TableTwoPaginator.pageSize}}</td> Thanks...!!!Longe
this.paginator.pageIndex == 0 ? i + 1 : 1 + i + this.paginator.pageIndex * this.paginator.pageSize can be shortened to simply this.paginator.pageIndex * this.paginator.pageSize + i + 1Sulphathiazole
H
42

Anyone using Angular6+ should use let i = dataIndex instead of let i = index as explained in this Github issue.

Here's the HTML snippet

<ng-container matColumnDef="position">
  <th mat-header-cell *matHeaderCellDef mat-sort-header> Num. </th>
  <td mat-cell *matCellDef="let element; let i = dataIndex">{{i + 1}}</td>
</ng-container>
Hemicellulose answered 15/9, 2020 at 12:53 Comment(3)
dataIndex - this is the right answer!! Thank you! So many answers but only this one is valid.Oliverolivera
This should definitely be the answer of the question.Ohare
This did not work for me with Angular 17, I had to stick to index otherwise I got no value.Millpond
B
33

You can use the filteredData property of your dataSource, like this:

<ng-container matColumnDef="weight">
  <th mat-header-cell *matHeaderCellDef> Header</th>
  <td mat-cell *matCellDef="let element"> {{dataSource.filteredData.indexOf(element)}} </td>
</ng-container>

Demo

With the @user3891850 solution(let i = index;), in case of pagination, the index will be the index in this page and not in the global object so you must be careful in case of pagination. example

Boutonniere answered 11/5, 2018 at 12:43 Comment(4)
This works {{dataSource.filteredData.indexOf(element)}}Bags
That's great, I used {{dataSource.filteredData.indexOf(element)+1}} to avoid the value 0. Thank u!!Encomiastic
Yeah, I'm surprised why all of them are ok with using index. Don't they use pagination... This is what we really need for paginated mat table..Natishanative
Do you know how many times the render get executed and every time you want to lookup for the index? This leads to low performance on big tables.Nations
T
11

In case you run into this issue and you are using a paginator the index you get here:

  <td mat-cell *matCellDef="let element; let i = index">{{i}}</td>

will be the current index displayed on the table. For instance, if you are on page 2 and your page size is 5, then the first index of the table will be 0 and not 5 (or the 6th item). So what you can do to get the true index is something like this:

index =
      this.paginator.pageIndex > 0
        ? index + this.paginator.pageIndex * this.paginator.pageSize
        : index;

If the paginator is on page one, index doesn't change. Otherwise multiply the pageIndex by the pageSize and add it to the index.

Thither answered 10/5, 2019 at 19:12 Comment(0)
W
7

I know this post is old but the above solution didn't work for me. instead if let i = index; try let i = dataIndex for latest version of mat-table check this solution. Don't know if it's just for expandable table though

Wasteland answered 24/8, 2019 at 19:37 Comment(1)
Worked on Angular 12Gavotte
G
7

increase position number in mat-table....

<ng-container matColumnDef="index">
  <th mat-header-cell *matHeaderCellDef> Sr.No </th>
  <td mat-cell *matCellDef="let i=index"> {{i+1}} </td>
</ng-container>
Guillory answered 12/11, 2019 at 13:29 Comment(0)
C
7

I found 2 cases when using Angular Material Table

  • Using *matCellDef="let row = index" if the table has one-row template
  • Using *matCellDef="let row = dataIndex" if the table has multiple row templates
Celluloid answered 25/12, 2021 at 1:40 Comment(0)
D
1

Include 'let i = index' in *matRowDef

Desecrate answered 18/9, 2019 at 9:3 Comment(0)
G
0

I searched a lot, but for my case "indexOf" scenario doesn't work properly then I found this answer, and it does exactly what I need.

let i = index;
i + (paginator.pageIndex * paginator.pageSize);
Gonzales answered 20/8, 2019 at 8:59 Comment(0)
N
0

  rindex:any;
  Cindex:any;

  show(){
    console.log("Column",this.Cindex,""+"Cell",this.rindex)

  }
  logIndex(j:any):void{
 this.Cindex=j

  }
  logIndex1(i:any):void{
    this.rindex=i

  }
  <ng-container *ngFor="let col of displayedColumns; index as i;" matColumnDef={{col}}>
                      <th mat-header-cell *matHeaderCellDef="">{{displayedColumnsNames[i]}}</th>
                      <td mat-cell *matCellDef="let element  ; "(click)="logIndex1(i) "> {{element[col]}} </td>
                  </ng-container>

                  <tr mat-header-row *matHeaderRowDef="displayedColumns;sticky :true   " ></tr>
                  <tr  mat-row *matRowDef="let row; columns: displayedColumns;  let j=index; "(click)="[logIndex(j),show()] " ></tr>
Nolannolana answered 11/7, 2022 at 6:52 Comment(1)
Please do not post code-only answers but explain your answer a little in textual form: Why and how does it work, what makes it different to the other answers given?Hafner

© 2022 - 2024 — McMap. All rights reserved.