How to expand row in a table using typescript or javascript

146 Views Asked by At

I have used angular 7.I am trying to expand and collapse table row by clicking name and place. But it is not opening properly. If i click place name, that place details only i want to show. But in my code it is opening all place details, Same for Name. How to resolve this issue.

app.component.html:

    <table class="table">
    <thead>
        <th> Name </th>
        <th> Place </th>
        <th> Phone </th>
    </thead> 
    <tbody> 
<ng-container *ngFor="let data of data1">
  <tr>
    <td (click)="expanded1 = !expanded1"> <a href="javascript:void(0)">{{data.name}}</a> </td>
    <td (click)="expanded2 = !expanded2"> <a href="javascript:void(0)">{{data.place}} </a></td>
    <td> {{data.phone}} </td>
  </tr>

  <ng-container *ngIf="expanded1">
    <tr>
      <td colspan="3">
      <div>Name Details:{{data.name}}</div>  
      </td> 
    </tr>
  </ng-container>

  <ng-container *ngIf="expanded2">
    <tr>
      <td colspan="3">
      <div>Place Details:{{data.place}}</div>  
      </td> 
    </tr>
  </ng-container>


</ng-container>
    </tbody>
</table>

app.component.ts:

export class AppComponent {
      expandContent = true;
      expanded1 = false;
      expanded2 = false;
      data1 = [{
        'name': 'john',
        'place': 'forest',
        'phone': '124-896-8963',
        'expanded': false
      }, {
        'name': 'Jay',
        'place': 'City',
        'phone': '124-896-1234',
        'expanded': false
      }, {
        'name': 'Joseph',
        'place': 'sky',
        'phone': '124-896-9632',
        'expanded': false
      },
      ]
       
    }

Demo: https://stackblitz.com/edit/angular-3hylrt?file=src%2Fapp%2Fapp.component.html

1

There are 1 best solutions below

12
On

You have a few problems. You are setting (click)="expanded1 = !expanded1" but then you are checking for *ngIf="expanded". This is a typo, but since you want to toggle each one individually you need to be setting data.expanded = !data.expanded instead of the shared boolean.

You are also setting the (click) on the <td> element for some reason, and then you make the link itself useless by adding href="javascript:void(0)" which will probably cancel the click event. Instead, put the click on the link since that's standard practice, and just change the CSS to make the link without an href appear clickable. You are using bootstrap, so just use the utility classes from that.

Also, not a "problem" but there's no need to wrap certain elements with a <ng-container> when you can just put the *ngIf="" directly on the <tr> element.

So here are the changes I am proposing

p {
  font-family: Lato;
}

tr a {
  cursor: pointer;
}
export class AppComponent {
  data1 = [
    {
      name: 'john',
      place: 'forest',
      phone: '124-896-8963',
      expanded1: false,
      expanded2: false,
    },
    {
      name: 'Jay',
      place: 'City',
      phone: '124-896-1234',
      expanded1: false,
      expanded2: false,
    },
    {
      name: 'Joseph',
      place: 'sky',
      phone: '124-896-9632',
      expanded1: false,
      expanded2: false,
    },
  ];
}
<ng-container *ngFor="let data of data1">
  <tr>
    <td>
      <a
        class="d-block link-primary"
        (click)="data.expanded1 = !data.expanded1">
        {{ data.name }}
      </a>
      {{data.expanded1}}
    </td>
    <td>
      <a
        class="d-block link-primary"
        (click)="data.expanded2 = !data.expanded2"
      >
        {{ data.place }}
      </a>
      {{data.expanded2}}
    </td>
    <td>{{ data.phone }}</td>
  </tr>
  <tr *ngIf="data.expanded1">
    <td colspan="3" class="bg-light">
      <div>Name Details:{{ data.name }}</div>
    </td>
  </tr>
  <tr *ngIf="data.expanded2">
    <td colspan="3" class="bg-light">
      <div>Place Details:{{ data.place }}</div>
    </td>
  </tr>
</ng-container>

StackBlitz Demo Here


Here is an example of how to modify an object by adding properties to each item in the array

const dataFromServer = [
  {
    name: 'john',
    place: 'forest',
    phone: '124-896-8963',
  },
  {
    name: 'Jay',
    place: 'City',
    phone: '124-896-1234',
  },
  {
    name: 'Joseph',
    place: 'sky',
    phone: '124-896-9632',
  },
];

const modifiedData = dataFromServer.map(d => {
  d.expanded1 = false;
  d.expanded2 = false;
  return d;
});

console.log(modifiedData);