How can a condition in ngIf be true only for the selected row

Viewed 1580

I am developing an angular project using Angular version 7. I have a table that shows some json objects. In each json object, I added 2 buttons, which I show conditionally when each one is selected.

What I mean is, when I click the Edit button, I want the No Edit button to be shown and vice versa ONLY FOR THE ROW I PRESSED THE BUTTON. But what is happening is that when I click the Edit button for a specific row, then all other buttons for the other rows change.

How can I do this?

myapp.component.html file:

<table>
    <thead>
      <tr>
        <th scope="col" translate>Name</th>
        <th scope="col" translate>Description</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor=" let product of products">
        <td>{{product.name}}</td>
        <td>{{datasource.description}}</td>
        <td>
          <button *ngIf="allowEdit" (click)="edit(product)">
            Edit
          </button>&nbsp;
          <button *ngIf="allowNoEdit" (click)="noEdit(product)">
            No Edit
          </button>&nbsp;
        </td>
      </tr>
    </tbody>
  </table>

myapp.component.ts file:

allowEdit: boolean = true;
allowNoEdit: boolean = false;

edit(product) {
   this.allowEdit= !this.allowEdit;
   this.allowNoEdit= !this.allowNoEdit;
}

noEdit(product) {
   this.allowEdit= !this.allowEdit;
   this.allowNoEdit= !this.allowNoEdit;
}
3 Answers

What about including the condition of showing such buttons as part of the json object? when clicking edit, you can modify then the flag of the specific json object (row) and show whatever you need

Initialize for every product a product.allowEdit = false. Then your Edit button would call an allowEdit(product)() function where you would change the flag inside product.allowEdit = !product.allowEdit;

myapp.component.html file:

<table>
    <thead>
      <tr>
        <th scope="col" translate>Name</th>
        <th scope="col" translate>Description</th>
      </tr>
    </thead>
<tbody>
  <tr *ngFor=" let product of products">
    <td>{{product.name}}</td>
    <td>{{datasource.description}}</td>
    <td>
      <button *ngIf="!product.showEdit" (click)="allowEdit(product)">
        Edit
      </button>&nbsp;
      <button  *ngIf="product.showEdit"(click)="noEdit(product)">
        No Edit
      </button>&nbsp;
    </td>
  </tr>
</tbody>

and inside your typescript

allowEdit(product) { 
     // in case you want to close all others editing products
     this.products.forEach(product => product.showEdit = false);
     product.showEdit = true;
}

noEdit(product) { 
     product.showEdit = false;
}

You can check it on this link: https://codepen.io/Mocni/pen/PrProv

You can dynamically add condition as "editable" key to your product object and check condition for making it editable or you can check on the already existing condition on product and your html will be

if you added editable key as boolean values to your object, so your html can be

<tbody>
  <tr *ngFor=" let product of products">
    <td>{{product.name}}</td>
    <td>{{datasource.description}}</td>
    <td>
      <button *ngIf="product.editable" (click)="allowEdit(product)">
        Edit
      </button>&nbsp;
      <button *ngIf="product.editable" (click)="noEdit(product)">
        No Edit
      </button>&nbsp;
    </td>
  </tr>
</tbody>

or if your object contains any generic value for all the list where button should be active:

<tbody>
<tr *ngFor=" let product of products">
<td>{{product.name}}</td>
<td>{{datasource.description}}</td>
<td>
  <button *ngIf="product.somecondition" (click)="allowEdit(product)">
    Edit
  </button>&nbsp;
  <button *ngIf="product.somecondition" (click)="noEdit(product)">
    No Edit
  </button>&nbsp;
</td>

Related