1

I am trying to make a table that, when you click a button, it needs to display the row directly beneath it.

I have had a look at this post, but I could not find an answer from it.

When I have it like below, it works, but the problem is, it displays all other hidden rows since they all share the same collapse variable.

This is the working example, but not 100% correct:

<table>
<thead>
  <th>Path out of this queue</th>
  <th *ngFor="let role of roles">{{role.RoleName}}</th>>
</thead>
<tbody>
  <ng-container *ngFor="let queue of workQueues; let i = index">
    <tr>
      <td><button (click)="collapse=!collapse">{{queue.WorkQueueName}}</button></td>
      <td *ngFor="let role of roles">
        <input type="checkbox" />
      </td>
    </tr>
    <tr *ngIf="collapse">
      Yay...
    </tr>
  </ng-container>
</tbody>

I thought I would be able to make the collapse variable unique, by appending the i, which is the index, to it, but then I get the following error:

Parser Error: Got interpolation ({{}}) where expression was expected

Here is my attempt:

<table>
<thead>
  <th>Path out of this queue</th>
  <th *ngFor="let role of roles">{{role.RoleName}}</th>>
</thead>
<tbody>
  <ng-container *ngFor="let queue of workQueues; let i = index">
    <tr>
      <td><button (click)="{{collapse+i}}={{!collapse+i}}">{{queue.WorkQueueName}}</button></td>
      <td *ngFor="let role of roles">
        <input type="checkbox" />
      </td>
    </tr>
    <tr *ngIf="{{collapse+i}}">
      Yay...
    </tr>
  </ng-container>
</tbody>

Specifically, in my (click) event, how can I make a unique variable that could be used?

monstertjie_za
  • 7,277
  • 8
  • 42
  • 73

1 Answers1

2
(click)="{{collapse+i}}={{!collapse+i}}"

should be

(click)="this[collapse+i] = !this[collapse+i]"

This allows you to use an indexer to obtain the field on the component. If it actually works depends on how you have collapse fields defined on your component.


Personally I would prefer extending the type contained in the workQueues array with an additional field.

(click)="queue.collapsed = !queue.collapsed"

...

<tr *ngIf="queue.collapsed">

An other alternative is to define a new field in the *ngFor.

<ng-container *ngFor="let queue of workQueues; let i = index; let isCollapsed = true">
<tr>
  <td><button (click)="isCollapsed = !isCollapsed">{{queue.WorkQueueName}}</button></td>
  <td *ngFor="let role of roles">
    <input type="checkbox" />
  </td>
</tr>
<tr *ngIf="!isCollapsed">
  Yay...
</tr>
</ng-container>

stackblitz

Igor
  • 60,821
  • 10
  • 100
  • 175
  • Let me give this a try real quick. Did not know about indexers in Typescript/javascript, but I do know of them in C# – monstertjie_za Mar 13 '19 at 18:46
  • This still expands all hidden rows, as with my first code block posted. – monstertjie_za Mar 13 '19 at 18:49
  • @monstertjie_za - like I said, it is hard to say if it works because I do not know the code in the component. Personally I would prefer options 2 or 3 that I included in the answer. – Igor Mar 13 '19 at 18:51
  • 3rd option produces: Cannot assign to a reference or variable! Think safest will be option two. – monstertjie_za Mar 13 '19 at 18:59
  • @monstertjie_za - See this [stackblitz](https://stackblitz.com/edit/angular-vmamga) for a working demo of option 3. – Igor Mar 13 '19 at 19:04
  • Check myne: https://stackblitz.com/edit/angular-79kvcs?file=src%2Fapp%2Fapp.component.html Works in Stackblits, but not in my application, and I literally copied the html over – monstertjie_za Mar 13 '19 at 19:12
  • @monstertjie_za - check that the casing and spelling is the same in your app. Accidentally creating a "new" variable with a mis-type is a common error that is difficult to catch and can easily duplicate that behavior. [Example stackblitz](https://stackblitz.com/edit/angular-u96bex) <= Here I "accidentally" defined it as `let sh0wItm = false` with a zero. – Igor Mar 13 '19 at 19:17
  • Thank for your assistance. I eventually decided to use the second approach. – monstertjie_za Mar 13 '19 at 19:20