user54226
user54226

Reputation: 107

Angular - Display message on specific item in a Loop

I have a list of rows using For Loop. Clicking on any row, pops up a modal window. The modal window contains a Cancel and Ok button. When clicked on OK button, a message should appear on the ROW which was clicked. Currently I can get the index number of the row and the message is showing on ALL rows when clicked OK. How can I display the message only on that specific ROW.

<div class="row" *ngFor="let item of items; let i = index">

<div class="row">
    <div class="col-2">
        <span (click)="showModalWindow">
            <img class="actionIcon" src="images/action.png" />
        </span>
    </div>
    <div class="col-4">
        <div class="ietm-img" *ngIf="item.image">
            <img [src]="item.image" alt="item" />
        </div>
    </div>
    <div class="col-6">
        <div class="text">
            <h6>{{item.name}}</h6>
            <p>MESSAGE NEEDS TO APPEAR ONLY ON THE SELECTED ROW</p>
            <span>{{item.measurement}} {{item.length}}</span>
        </div>
    </div>
</div>

Upvotes: 0

Views: 1019

Answers (2)

Steve Giles
Steve Giles

Reputation: 240

Since your data appears to be coming from an API you may not have the ability to add an additional property to track the selected state of the row.

Consider capturing the selected row when the row is clicked, like so,

<span (click)="showModalWindow(); selectedRow=i" style="border:1px solid red">

Then you can set the hidden state when the row is clicked,

<p [hidden]="selectedRow !== i">MESSAGE NEEDS TO APPEAR ONLY ON THE SELECTED ROW</p>

In your component you'll need a variable to capture the state

selectedRow: Number;`

The completed template would look something like this:

<div class="row" *ngFor="let item of items; let i = index">
  <div class="row">
    <div class="col-2">
          <span (click)="showModalWindow(); selectedRow=i" style="border:1px solid red">
              <img class="actionIcon" src="images/action.png" />
          </span>
    </div>
    <div class="col-4">
      <div class="ietm-img" *ngIf="item.image">
        <img [src]="item.image" alt="item" />
      </div>
    </div>
    <div class="col-6">
      <div class="text">
        <h6>{{item.name}}</h6>
        <p [hidden]="selectedRow !== i">MESSAGE NEEDS TO APPEAR ONLY ON THE SELECTED ROW</p>
        <span>{{item.measurement}} {{item.length}}</span>
      </div>
    </div>
  </div>
</div>

Upvotes: 1

Barremian
Barremian

Reputation: 31125

I believe there are multiple ways to do it. One way would be to introduce an additional boolean property (eg. clicked) in the items array of objects.

items = [
  {
    'name': 'sample',
    'measurement': 'sample',
    'clicked': false,
    ...
  },
  ...
]

And set that property to true when the OK button is clicked in the modal. Now you could check this property using *ngIf in the template to display the message.

Template

<div class="col-6">
  <div class="text">
    <h6>{{item.name}}</h6>
    <ng-container *ngIf="item.clicked">      <!-- check condition -->
      <p>MESSAGE NEEDS TO APPEAR ONLY ON THE SELECTED ROW</p>
    </ng-container>
    <span>{{item.measurement}} {{item.length}}</span>
  </div>
</div>

Update: add clicked property

You could introduce the clicked property to the data obtained from the API before assigning it to the items variable.

this.apiService.getItems().pipe(
  map(items => items.map(item => ({ ...item, clicked: false });
).subscribe(
  items => { this.items = items },
  error => { }
);

Now there is property called clicked in each object of the array. Set it to false if an object is opened in the template and the OK button is clicked in the modal.

Upvotes: 0

Related Questions