How to Add Serial Number in a Mat Table in Angular?

When we have a large number of records in our mat table, we generally reserve the very first column of the mat table to show the serial number.

One way to add the serial number to your mat table is to explicitly assign the serial number to each record using a for or while loop and then display it inside the mat table. But this approach is somewhat lengthy as we have to explicitly assign the serial number.

So, we will use another simpler approach where we will use the current index of the ngFor loop to add the serial number dynamically.

Just like a normal for loop, the index of the ngFor also starts with 0. So, if we want to start the serial number from 1 we have to add 1 in the current index.

You just need to add the below code to any table cell in which you want to display the serial number:

<!-- Add serial number to a mat table -->
<td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }} </td>

Let’s understand it with the help of a real-time example.

Let’s assume we have a table with five columns Sr. No, firstName, lastName, email and phone. We want to dynamically generate the serial number in the very first column of the mat table.

Here is the full HTML code that we need to add to our component’s template file:

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

    <!-- Id Column -->
    <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef> Sr. No. </th>
        <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }} </td>
    </ng-container>

    <!-- First Name Column -->
    <ng-container matColumnDef="firstName">
        <th mat-header-cell *matHeaderCellDef> First Name </th>
        <td mat-cell *matCellDef="let element"> {{element.firstName}} </td>
    </ng-container>

    <!-- Last Name Column -->
    <ng-container matColumnDef="lastName">
        <th mat-header-cell *matHeaderCellDef> Last Name </th>
        <td mat-cell *matCellDef="let element"> {{element.lastName}} </td>
    </ng-container>

    <!-- Email Column -->
    <ng-container matColumnDef="email">
        <th mat-header-cell *matHeaderCellDef> Email </th>
        <td mat-cell *matCellDef="let element"> {{element.email}} </td>
    </ng-container>

    <!-- Phone No. Column -->
    <ng-container matColumnDef="phone">
        <th mat-header-cell *matHeaderCellDef> Phone </th>
        <td mat-cell *matCellDef="let element"> {{element.phone}} </td>
    </ng-container>

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

After compilation, the above code will produce the following sample output:

Add serial number to a mat table in Angular

As you can see from the above image, the serial number is automatically generated inside the first column of the mat table.


Add Serial Number with Mat-Paginator

If you are not using mat-paginator i.e. the whole table data is being shown in just a single page, then only the above solution works fine.

But, if you are using mat-paginator and the mat table data is divided into multiple pages then the above technique will not work properly. In that case, every page(first, second, third…) of the mat table will start from serial number 1 which is incorrect.

For example, if we are showing 5 items per page and we move to second page of the mat table then the serial number should start from 6, for the third page it should start from 11 and so on. But, with the above solution i.e. {{i + 1}}, it would always start with 1.

To solve this problem, we will take help of the current page index and the current choosen page size.

For the current page index we can use the paginator.pageIndex property and for the current choosen page size we can use the paginator.pageSize property. Here, paginator is the reference to the mat-paginator.

So, instead of {{ i + 1}}, you should use the following code in the serial number column:

{{ paginator.pageIndex*paginator.pageSize + (i + 1) }}

Below is the updated mat-table along with a mat-paginator:

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

    <!-- Id Column -->
    <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef> Sr. No. </th>
        <td mat-cell *matCellDef="let element; let i = index;"> 
            {{ paginator.pageIndex*paginator.pageSize + (i + 1) }} 
        </td>
    </ng-container>

    <!-- First Name Column -->
    <ng-container matColumnDef="firstName">
        <th mat-header-cell *matHeaderCellDef> First Name </th>
        <td mat-cell *matCellDef="let element"> {{element.firstName}} </td>
    </ng-container>

    <!-- Last Name Column -->
    <ng-container matColumnDef="lastName">
        <th mat-header-cell *matHeaderCellDef> Last Name </th>
        <td mat-cell *matCellDef="let element"> {{element.lastName}} </td>
    </ng-container>

    <!-- Email Column -->
    <ng-container matColumnDef="email">
        <th mat-header-cell *matHeaderCellDef> Email </th>
        <td mat-cell *matCellDef="let element"> {{element.email}} </td>
    </ng-container>

    <!-- Phone No. Column -->
    <ng-container matColumnDef="phone">
        <th mat-header-cell *matHeaderCellDef> Phone </th>
        <td mat-cell *matCellDef="let element"> {{element.phone}} </td>
    </ng-container>

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

<!-- Mat Paginator -->
<mat-paginator 
    #paginator 
    [length]="15" 
    [pageSize]="5" 
    [pageSizeOptions]="[5, 10, 25, 100]" showFirstLastButtons>
</mat-paginator>

After compilation, the above mat-table will produce the following sample output on the second page of the mat table:

Serial number in mat table with mat-paginator

As you can see from the above image, the serial number on the second page is starting from 6 as we are showing 5 records per page.

For the third page it will start from 11 and so on.

Thanks for reading.


Author

  • Manoj Kumar

    Hi, My name is Manoj Kumar. I am a full-stack developer with a passion for creating robust and efficient web applications. I have hands-on experience with a diverse set of technologies, including but not limited to HTML, CSS, JavaScript, TypeScript, Angular, Node.js, Express, React, and MongoDB.

    View all posts