KB_
KB_

Reputation: 2123

How to show clicked element in *ngFor list hiding others using Angular 2

I want the clicked element in ngFof to display info hidden by ngIf. Right now clicking on an image all hidden elements are displayed. How to show the info of the single clicked image?

I do not use jquery in my example because I could not get it to work. I am looking to find out how to do it in angular2 before accepting other solutions. plunker

 @Component({

  selector: 'hello-world',
  template: 'src/hello_world.html',
  directives: [FORM_DIRECTIVES, CORE_DIRECTIVES]

})
export class HelloWorld {

    clicked() {// only show clicked img info 
      e=event.target;
      console.log(e);
      this.show=!this.show;
  };

  info = [{
    data: "information for img1:",
    data2: "only the info img1 is displayed"
  },
    {
      data: "information for img2:",
      data2: "only the info for img2 is displayed"
    },
    {
      data: "information for img3:",
      data2: "only the  info for img3 is displayed"
    }]
}
<div  *ngFor="#x of info">
<img src="http://lorempixel.com/150/150"  (click)="clicked($event)" >


  <div *ngIf="show">
      <div class="names">
        <div class="fullName">{{x.data}}</div>
        <div>{{x.data2}}</div>
      </div>
    </div>
</div>

I found this post that has a similar problem albeit I could not implement it in my code. angular2-get-reference-to-element-created-in-ngfor

Upvotes: 5

Views: 12045

Answers (3)

Surya R Praveen
Surya R Praveen

Reputation: 3745

Keep a track of selected / clicked id as a seperate component

<ul>
  <li *ngFor="let x of things; let i = index;" (click)="toggleOptionsMenu(x.id)" [class.show-more]="x.id === selectedId">{{x}}</li>
</ul> 

selectedId = null;
toggleOptionsMenu(id) {
  this.selectedId = id;
}

Upvotes: 1

user1752532
user1752532

Reputation:

Just though I would add my 2 cents on this question, mainly because if you are getting data from an api you will not be able to manipulate the data to have a boolean property without first pushing onto the array as well as wanting an easier toggle on elements.

The *ngFor can hold the index with a simple *ngFor="let item of items; let i = index". So we can easily find which index we are handling when we initially hit the (click) action and pass in that index to the method (click)="action(i)".

The method can then assign a variable which can be used in a conditional in the *ngIf in the element you want to show and hide.

action(index){
   this.showElement = index; // assign variable to a number to be used in 
                             // a conditional on the *ngIf
}

We now have a variable equal to the clicked index and can therefore create a conditional based on the variable and the index looping in the *ngFor. So in the html we can add

<div *ngIf="showElement === i"> Toggled visibility element </div>

So in the case posted by the OP

component

export class HelloWorld {
   public show:number;

   constructor(){}

   clicked(index){
      this.show = index;
   };
}

html

<div *ngFor="let x of things; let i = index">
   <img src="http://lorempixel.com/150/150" alt="loading" (click)="clicked(i)" >  

   <div *ngIf="show === i">
       <div class="names">
       <div class="fullName">{{x.data}}</div>
       <div>{{x.data2}}</div>
    </div>
</div>

Not sure if there is maybe a better way, just dont think that manipulating the data is the best approach to solve view functionality.

Upvotes: 3

dieuhd
dieuhd

Reputation: 1326

Each row data, should use a var show: Here is my code:

    export class HelloWorld {
      public show:boolean = false;
      clicked(index) {// only show clicked img info 
        console.log(this.things[index]);
        this.things[index].show = !this.things[index].show;
      };

    public things:Array<any> = [{
    data: "information for img1:",
    data2: "only the info img1 is displayed",
    show: false
  },
    {
      data: "information for img2:",
      data2: "only the info for img2 is displayed"
    },
    {
      data: "information for img3:",
      data2: "only the  info for img3 is displayed"
    }]


}

and in html

<h3>How to show info of clicked image only </h3>

<div  *ngFor="#x of things;#i = index">
<img src="http://lorempixel.com/150/150" alt="loading" (click)="clicked(i)" >


  <div *ngIf="x.show">
      <div class="names">
        <div class="fullName">{{x.data}}</div>
        <div>{{x.data2}}</div>
      </div>
    </div>
</div>

https://plnkr.co/edit/SR2Iguzrgd6DpquCZygc?p=preview

Upvotes: 4

Related Questions