Dave
Dave

Reputation: 91

Angular NgFor collapse data inside TR

I'm doing an ngfor on returning my API to a table, and I need to hide/show a line of details from my table, but that line is outside my ngfor, so I can't bind my ngfor data. Can you help me? Is there a way to do this? I thought about using an ng-container but I didn't understand it very well.

My Component:

export class MachinesComponent implements OnInit, OnDestroy {

  constructor(private machine: MachineService) { }

  public isMenuCollapsed = true;
  public machines: any[] = [];
  private alive: boolean = true;

  ngOnInit(): void {
    this.machine.getMachines()
      .takeWhile(() => this.alive)
      .subscribe((machine) => this.machines = machine['servers']);
  }
}

My Html code:

<section class="main-content" *ngIf="machines.length >0">
    <table class="table">
      <thead>
        <tr>
          <th>Machine</th>
          <th>Status</th>
          <th>Disk</th>
          <th>RAM</th>
          <th>VCPU</th>
          <th scope="col">Action</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let machine of machines">
          <td (click)="isMenuCollapsed = !isMenuCollapsed">
            <div class="user-info">
              <div class="user-info__img">
                <img src="./assets/img/cloud2.svg" alt="Usuário Img">
              </div>
              <div class="user-info__basic">
                <h5 class="mb-0">{{machine.name}}</h5>
              </div>
            </div>
          </td>
          <td (click)="isMenuCollapsed = !isMenuCollapsed">
            <span class="active-circle bg-success"></span> Active
          </td>
          <td (click)="isMenuCollapsed = !isMenuCollapsed">{{machine?.flavor?.disk}} GB</td>
          <td (click)="isMenuCollapsed = !isMenuCollapsed">{{machine?.flavor?.ram}} GB</td>
          <td (click)="isMenuCollapsed = !isMenuCollapsed">{{machine?.flavor?.vcpus}}x 2.8Mbps</td>
          <td >
              <button type="button" class="btn btn-primary mr-2" ngbTooltip="Open"><i class="fas fa-external-link-alt"></i></button>
              <button type="button" class="btn btn-primary mr-2" ngbTooltip="Detail"><i class="far fa-eye"></i></button>
              <button type="button" class="btn btn-primary mr-2" ngbTooltip="Detail"><i class="fas fa-edit"></i></button>
              <button type="button" class="btn btn-danger" ngbTooltip="Delete"><i class="far fa-trash-alt"></i></button>
          </td>
        </tr>

         <!-- I need the ngfor data inside this TR line collapse -->
        <tr class="collapse cell-1 row-child" [ngbCollapse]="isMenuCollapsed">
          <td (click)="isMenuCollapsed = true" class="text-center"><i class="fa fa-angle-up"></i></td>
          <td>Product&nbsp;</td>
          <td>iTelefone SX with ratina display</td>
          <td>QTY</td>
          <td>2</td>
          <td>2</td>
        </tr>
      </tbody>
    </table>
</section>

Upvotes: 3

Views: 478

Answers (1)

IAfanasov
IAfanasov

Reputation: 4993

If I understand correctly, you want to show clicked item in the last table row. Here is the solution

Component:

export class MachinesComponent implements OnInit, OnDestroy {
  // Convention is to put properties before the constructor
  public machines: any[] = [];
  private alive: boolean = true;
  // This property is added
  public selectedMachine: any;

  constructor(private machine: MachineService) { }

  ngOnInit(): void {
    this.machine.getMachines()
      .takeWhile(() => this.alive)
      .subscribe((machine) => this.machines = machine['servers']);
  }
}

Html code:

<section class="main-content" *ngIf="machines.length >0">
    <table class="table">
      <thead>
        <tr>
          <th>Machine</th>
          <th>Status</th>
          <th>Disk</th>
          <th>RAM</th>
          <th>VCPU</th>
          <th scope="col">Action</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let machine of machines">
          <td (click)="selectedMachine = machine">
            <div class="user-info">
              <div class="user-info__img">
                <img src="./assets/img/cloud2.svg" alt="Usuário Img">
              </div>
              <div class="user-info__basic">
                <h5 class="mb-0">{{machine.name}}</h5>
              </div>
            </div>
          </td>
          <td (click)="selectedMachine = machine">
            <span class="active-circle bg-success"></span> Active
          </td>
          <td (click)="selectedMachine = machine">{{machine?.flavor?.disk}} GB</td>
          <td (click)="selectedMachine = machine">{{machine?.flavor?.ram}} GB</td>
          <td (click)="selectedMachine = machine">{{machine?.flavor?.vcpus}}x 2.8Mbps</td>
          <td >
              <button type="button" class="btn btn-primary mr-2" ngbTooltip="Open"><i class="fas fa-external-link-alt"></i></button>
              <button type="button" class="btn btn-primary mr-2" ngbTooltip="Detail"><i class="far fa-eye"></i></button>
              <button type="button" class="btn btn-primary mr-2" ngbTooltip="Detail"><i class="fas fa-edit"></i></button>
              <button type="button" class="btn btn-danger" ngbTooltip="Delete"><i class="far fa-trash-alt"></i></button>
          </td>
        </tr>

         <!-- I need the ngfor data inside this TR line collapse -->
        <tr class="collapse cell-1 row-child" [ngbCollapse]="!selectedMachine">
          <td (click)="selectedMachine = null" class="text-center"><i class="fa fa-angle-up"></i></td>
          <td>Product&nbsp;</td>
          <td>iTelefone SX with ratina display</td>
          <td>QTY</td>
          <td>2</td>
          <td>2</td>
        </tr>
      </tbody>
    </table>
</section>

Upvotes: 1

Related Questions