Angular expand/collapsible table Row - using ng-bootstrap - javascript

I am creating an application, where when clicking on the TR of my table, I need the line to be expanded to show the details.
However, when doing this, all the lines expand showing the data of the line that was clicked as in the result of the image below.
can you help me?
Image row expanded result:
https://imgur.com/a/NmCiV9Q
My code:
<tbody>
<ng-container *ngFor="let machine of machines">
<tr (click)="selectedMachine = machine">
<td>
<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> Status
</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" (click)="openMachine(machine.id)"><i class="fas fa-external-link-alt"></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>
<ng-container *ngIf="selectedMachine">
<tr [ngbCollapse]="!selectedMachine">
<td (click)="selectedMachine = null" class="text-center"><i class="fa fa-angle-up"></i></td>
<td>hello</td>
<td>{{selectedMachine?.flavor?.swap}}</td>
<td>{{selectedMachine?.flavor?.id}}</td>
<td>2</td>
<td>2</td>
</tr>
</ng-container>
</ng-container>
</tbody>
My Component:
export class MachinesComponent implements OnInit, OnDestroy {
constructor(private machine: MachineService) { }
public selectedMachine: any;
public machines: any[] = [];
}

<ng-container *ngIf="selectedMachine"> is placed inside the means <ng-container *ngFor="let machine of machines">. You can read it as for every machine show the selectedMachine container whenever item is selected. I feel that what you want is:
<tbody>
<ng-container *ngFor="let machine of machines">
...
<ng-container *ngIf="selectedMachine === machine">
<tr [ngbCollapse]="!selectedMachine">
<td (click)="selectedMachine = null" class="text-center"><i class="fa fa-angle-up"></i></td>
<td>hello</td>
<td>{{selectedMachine?.flavor?.swap}}</td>
<td>{{selectedMachine?.flavor?.id}}</td>
<td>2</td>
<td>2</td>
</tr>
</ng-container>
</ng-container>
</tbody>
it will show the details of the selected machine only next to this machine.

Related

AlpineJS loop inside loop to add table row

I need help to solve this problem, i know AlpineJs must use something for "fragments", its fine when i workin on div, but when i do loop table row, and have another row, it become a problem, because i cant use div for the fragment. is there any solution?
here's my code
<template x-for="data in data">
<tr>
<td>
<div class="d-flex justify-content-between">
<i class="fa fa-lock"></i>
<i class="fa fa-caret-up"></i>
</div>
</td>
<td>100</td>
<td>Akun 1</td>
<td>Kategori Akun A</td>
<td class="text-end">Rp 0,00</td>
</tr>
<template x-for="data2 in data.children">
<tr>
<td>
<div class="d-flex justify-content-between">
<i class="fa fa-lock"></i>
<i class="fa fa-caret-up"></i>
</div>
</td>
<td>100</td>
<td>Akun 1</td>
<td>Kategori Akun A</td>
<td class="text-end">Rp 0,00</td>
</tr>
<template x-for="data3 in data2.children">
<tr>
<td>
<div class="d-flex justify-content-between">
<i class="fa fa-lock"></i>
<i class="fa fa-caret-up"></i>
</div>
</td>
<td>100</td>
<td>Akun 1</td>
<td>Kategori Akun A</td>
<td class="text-end">Rp 0,00</td>
</tr>
</template>
</template>
</template>

How to edit particular row inline edit using Angular8

Hi I am using Angular8 and initially, it must be bound in a table all values and when click on edit, that particular row should be editable and one row at a time can be edited, I have attached the demo. And here I have added only one array data for demo purposes, but I need to bind multiple years so I tried with reactive forms to add input field and td based on click but couldn't bind values. So here in my case, I need to edit one row at a time.
HTML:
<ng-container *ngFor="let contact of yearManagement">
<tr>
<td></td>
<td class="text-capitalize">{{contact.policyTypeName}}</td>
<td>{{contact.quotes}}</td>
<td>{{contact.policyCT}}</td>
<td>{{contact.writtenPremium }}</td>
<td class="width125">
<button class="btn btn-outline-primary btn-table ml-1" title="Edit">Edit</button>
<button class="btn btn-outline-primary btn-table ml-1" title="Delete"
(click)="deleteCommitment(contact)">Delete</button>
</td>
</tr>
</ng-container>
Demo
Try with the following changes in html
<ng-container *ngFor="let contact of yearManagement">
<tr>
<td></td>
<td class="text-capitalize">
<ng-container *ngIf="editableRow !== contact.id; else newDeb">
{{contact.policyTypeName}}
</ng-container>
<ng-template #newDeb>
<input [(ngModel)]="contact.policyTypeName" />
</ng-template>
</td>
<td>{{contact.quotes}}</td>
<td>{{contact.policyCT}}</td>
<td>{{contact.writtenPremium }}</td>
<td class="width125">
<button class="btn btn-outline-primary btn-table ml-1" title="Edit"
(click)="editableRow = contact.id">Edit</button>
<button class="btn btn-outline-primary btn-table ml-1" title="Delete"
(click)="deleteCommitment(contact)">Delete</button>
</td>
</tr>
</ng-container>
And in typescript
export class AppComponent {
editableRow = 0;

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 </td>
<td>iTelefone SX with ratina display</td>
<td>QTY</td>
<td>2</td>
<td>2</td>
</tr>
</tbody>
</table>
</section>
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 </td>
<td>iTelefone SX with ratina display</td>
<td>QTY</td>
<td>2</td>
<td>2</td>
</tr>
</tbody>
</table>
</section>

How can I create expand/collapse function for each row of table? Angular6

So I need to be able to expand some details on each row of a table. Right now I'm having two issues:
Clicking the expand/collapse toggle will trigger the action for every row in the table.
The first row always puts the details above it.
Here's the code segment:
<tbody>
<tr *ngFor="let client of clients">
<td class="details-control">
<a class="btn btn-link" (click)="collapsed1=!collapsed1">
<i class="material-icons">
expand_more
</i>
</a>
</td>
<td>{{client.firstName}}</td>
<td>{{client.lastName}}</td>
<td>{{client.company}}</td>
<td><input type="checkbox"></td>
</tr>
<div *ngIf="!collapsed1">
<p>Details</p>
</div>
</tbody>
And what it looks like:
Toggling
Also I had my *ngFor statement in the tag earlier but I realized I can't hit individual client objects if I build a separate for details.
Let me know how I can improve!
It's a very common pattern.
The best and quick solution is to use some ID instead of just a boolean in your collapsed1 variable.
<tbody>
<tr *ngFor="let client of clients">
<td class="details-control">
<a class="btn btn-link" (click)="collapsed1 = collapsed1 ? 0 : client.id ">
<i class="material-icons">
expand_more
</i>
</a>
</td>
<td>{{client.firstName}}</td>
<td>{{client.lastName}}</td>
<td>{{client.company}}</td>
<td><input type="checkbox"></td>
<div *ngIf="collapsed1=client.id">
<p>Details</p>
</div>
You need a boolean array collapsed[] and use index in your ngFor, so you can use collapsed[i]. Take a look here for using index in ngFor:
ngFor using Index
Let me know if you need more info. Wellcome
Nevermind, here is the code that solved it.
<tbody>
<tr *ngFor="let client of clients; let i = index">
<td class="details-control">
<a class="btn btn-link" (click)="client.hideme=!client.hideme">
<i class="material-icons" *ngIf="!client.hideme">
expand_more
</i>
<i class="material-icons" *ngIf="client.hideme">
expand_less
</i>
</a>
</td>
<td width="30%">{{client.firstName}}
<tr *ngIf="client.hideme">
<td>Hey, I'm a bunch of details!</td>
</tr>
</td>
<td>{{client.lastName}}</td>
<td>{{client.company}}
<tr *ngIf="client.hideme">
<td>More Issuer details</td>
</tr>
</td>
<td><input type="checkbox"></td>
</tr>
</tbody>

expand and collapse row for ng-table not working

I am trying to achieve an expand and collapse row for ng-table, basically what I want is if you click on row it expands with more detail.But currently all the rows get expanded on click. Does anyone know how to achieve this?
Any help appreciated thanks
<table ng-table="tableParams" class="table table-striped">
<tr ng-repeat-start="ticket in ng">
<td data-title="'Id'">{{ticket.requestId}}</td>
<td style="width:60%;" data-title="'Subject'" >{{ticket.subject}}</td>
<td data-title="'State'"><span ng-class="ticket.state+'Color'">{{ticket.state}}</span></td>
<td data-title="'Priority'">{{ticket.priority}}</td>
<td >
<a ui-sref="app.detail({id: ticket.requestId})" class="btn btn-transparent btn-xs" tooltip-placement="top" tooltip="Edit"><i class="fa fa-pencil"></i></a>
<!-- <a class="btn btn-transparent btn-xs tooltips" tooltip-placement="top" tooltip="Expand" ng-click="toggleDetail($index);lastComment(ticket.requestId)"><i class="fa" >+/-</i></a>-->
<button ng-if="user.expanded" ng-click="user.expanded = false">-</button>
<button ng-if="!user.expanded" ng-click="user.expanded = true">+</button>
</td>
</tr>
<tr ng-if="user.expanded" ng-repeat-end="" >
<td colspan="8" >Test</td>
</tr>
</table>
You have to put your variable expanded for your line instead of a general var. It means that it won't be user.expanded but it have to be ticket.expanded
<table ng-table="tableParams" class="table table-striped">
<tr ng-repeat-start="ticket in ng">
<td data-title="'Id'">{{ticket.requestId}}</td>
<td style="width:60%;" data-title="'Subject'" >{{ticket.subject}}</td>
<td data-title="'State'"><span ng-class="ticket.state+'Color'">{{ticket.state}}</span></td>
<td data-title="'Priority'">{{ticket.priority}}</td>
<td >
<a ui-sref="app.detail({id: ticket.requestId})" class="btn btn-transparent btn-xs" tooltip-placement="top" tooltip="Edit"><i class="fa fa-pencil"></i></a>
<!-- <a class="btn btn-transparent btn-xs tooltips" tooltip-placement="top" tooltip="Expand" ng-click="toggleDetail($index);lastComment(ticket.requestId)"><i class="fa" >+/-</i></a>-->
<button ng-if="ticket.expanded" ng-click="ticket.expanded = false">-</button>
<button ng-if="!ticket.expanded" ng-click="ticket.expanded = true">+</button>
</td>
</tr>
<tr ng-if="ticket.expanded" ng-repeat-end="" >
<td colspan="8" >Test</td>
</tr>
</table>
Working Fiddle

Categories

Resources