Shilpa Nagavara
Shilpa Nagavara

Reputation: 1165

Angular ngFor spanning two rows (expand/collapse)

I have an angular application. I need display a list of data in a table. I have applied ngFor on the TR element of the table. However, when each row is expanded, another row with additional details about the item must be displayed.

Collapsed view: enter image description here

Expanded view: enter image description here

Code:

<table>
  <thead>
  <tr>Header here</tr>
  </thead>
  
  <tbody>
    <tr *ngFor="let item of results">
      + Collapsed Row
      <!-- How do I display the expanded row and display additional details when + symbol is clicked? -->
    </tr>
    
  </tbody>
</table>

Upvotes: 2

Views: 7097

Answers (2)

Thacio Pacifico
Thacio Pacifico

Reputation: 69

I faced it the same problem and i didn't find any good solution. But after a deep reseach i found this ng-container and it worked very well. U can see it in action bellow

https://plnkr.co/edit/F8ohXKLHvvbHXAqGESQN?p=preview

  <ng-container *ngFor="let obj of posts">
            <tr>
                <td>
                    <button (click)="openCloseRow(obj.id)">
                        <span *ngIf="rowSelected!=obj.id; else close">Open</span>
                          <ng-template #close>
                            <span>Close</span>
                            </ng-template>
                    </button>
                </td> 
              <td>{{obj.date}}</td>
              <td>
                  {{obj.subject}}
              </td>
              <td>{{obj.numComents}}</td>
            </tr>
            <tr *ngIf="rowSelected==obj.id">
                <td></td>
                <td colspan="4">
                    <table class="table table-striped">
                        <thead>
                            <tr>                                   
                                <th style="width:15%;">Comment</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr *ngFor="let q of obj.comments">                                  
                                <td style="width:15%;">{{q}}</td>
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
          </ng-container>

Upvotes: 2

CozyAzure
CozyAzure

Reputation: 8468

If you just want a simple expand and collapse row, then a simple ngIf will do the trick:

<tr *ngFor="let item of results">
  <div (click)="item.expanded=!item.expanded">+ Collapsed Row</div>
  <span *ngIf="item.expanded">This is an expanded content</span>
</tr>

However, if you want to have only one row to be expanded at a time, then you need to keep track on which row is expanded.

In your html:

<tr *ngFor="let item of results; let $index=index;">
  <div (click)="expandRow($index)">+ Collapsed Row</div>
  <span *ngIf="$index === expandedIndex">This is an expanded content</span>
</tr>

In your component, initialize a variable called expandedIndex with the value of -1. This ensures all rows are collapsed when the component is inited. You can do it either at constructor level or at ngOnInit, it doesn't really matter:

constructor(public expandedIndex:number){
   this.expandedIndex=-1;
}

Then, have a named function called expandRow:

  expandRow(index: number): void {
    this.expandedIndex = index === this.expandedIndex ? -1 : index;
  }

Upvotes: 10

Related Questions