Search code examples
angularangular-material-table

Angular Material Table with expandable rows opening one row is closing already opened row


I am using Angular Material Table with expandable rows to close and open for my "avroMsg" data column. My requirement is open row should not be closed if I click on to open another row. Opened should not be closed. Opened row should be closed only when I again clicked on it for second time.

<table mat-table [dataSource]="dataSource"  matSort multiTemplateDataRows                       class="mat-elevation-z8">
                         @for (column of columnsToDisplay; track column) {
                             <ng-container matColumnDef="{{column}}">
                                 <th mat-header-cell *matHeaderCellDef>
    
                                    @if(column=='Sta'){
                                        DEP
                                    }@if(column=='event'){
                                        EVENT
                                    }                                    
                                    @if(column=='srcTimestamp'){
                                        GENERATED TIME
                                    }
                                    @if(column=='insTimestamp'){
                                        RECORDED TIME
                                    }
                                     
                                    </th>
                                 <td mat-cell *matCellDef="let element"> {{element[column]}} </td>
                             </ng-container>
                         }
                   <ng-container matColumnDef="expand">
                     <th mat-header-cell *matHeaderCellDef aria-label="row actions">&nbsp;</th>
                     <td mat-cell *matCellDef="let element">
                       <button mat-icon-button aria-label="expand row" (click)="(expandedElement = expandedElement === element ? null : element); $event.stopPropagation()">
                         @if (expandedElement === element) {
                           <mat-icon>keyboard_arrow_up</mat-icon>
                         } @else {
                           <mat-icon>keyboard_arrow_down</mat-icon>
                         }
                       </button>
                     </td>
                   </ng-container>
                 
                   <ng-container matColumnDef="expandedDetail">
                     <td mat-cell *matCellDef="let element" [attr.colspan]="columnsToDisplayWithExpand.length">
                       <div class="example-element-detail"
                            [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
                         
                         <div class="example-element-description">
                             
                         <textarea readonly matInput style="height: 200px; width:750px;overflow-y: auto;font-family: 'Bradley Hand', cursive;background-color: beige;">
                             
                             {{element.avroMsg |json}}
                             
                         </textarea>                         
             
                         </div>
                         <div>
                            <button mat-button mat-raised-button [cdkCopyToClipboard]="element.avroMsg |json">Copy</button>
                         </div>
                         
                       </div>
                     </td>
                   </ng-container>
                 
                   <tr mat-header-row *matHeaderRowDef="columnsToDisplayWithExpand;sticky: true"></tr>
                   <tr mat-row *matRowDef="let element; columns: columnsToDisplayWithExpand;let index = dataIndex;"
                       [ngClass]="{alternate: index % 2 == 0 }"
                       class="example-element-row"
                       [class.example-expanded-row]="expandedElement === element"
                       (click)="expandedElement = expandedElement === element ? null : element">
                   </tr>
                   <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="example-detail-row"></tr>
                 </table>

How to achieve this? Appreciate your help. Why other first row is closing when clicked on second row.


Solution

  • See your code and try answer: What it's the reason the row is expanded?

    Yes, when element == expandedElement

      [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'"
    

    and you equal element to expandedElement when you click the row (if the row is yet expanded expandedElement becomes null):

    <tr ... (click)="expandedElement = expandedElement === element ? null : element">
    

    Well, add a new property to your array, (call it e.g. "expanded") and you use

      [@detailExpand]="element.expanded ? 'expanded' : 'collapsed'"
    

    and

    <tr ... (click)="element.expanded=!element.expanded">