0

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 Answer 1

2

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);

12
  • It is opening all. Why?
    – sarann
    Commented Nov 15, 2023 at 16:59
  • Sorry, fix that
    – Chris Barr
    Commented Nov 15, 2023 at 17:00
  • I am trying without adding expanded1 and expaneded2 property in the array object
    – sarann
    Commented Nov 15, 2023 at 17:11
  • Can you check this code correct or not? stackblitz.com/edit/…
    – sarann
    Commented Nov 15, 2023 at 17:15
  • So, yes in general you are doing it right but you need to have the initial property values on each item in your data1 array so they can be unique to each item. Check my updated answer
    – Chris Barr
    Commented Nov 15, 2023 at 17:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.