24

I have a bunch of list items and would like to highlight each one once it's clicked. This is easy for me to do in jQuery or even JavaScript but I'm lost when it comes to Angular2.

<ul>
   <li [attr.data-selected]="false" (click)="highlightItem($event)" [class.highlight]="isHighlighted($event)" *ngFor="#item of items"> {{item}} </li>
</ul>

My component

export class HelloWorld {
    items = ["pineapples", "apples", "tomatoes", "bread"];

    highlightItem(event) {
        event.target.setAttribute("data-selected", "true");
   }

   isHighlighted(event) {
       return event.target.getAttribute("data-selected") == "true";
    }
}

Not sure where my mistake is or if I'm using a wrong method

5 Answers 5

23

You need to make an array in your class to store highlight status of an item:

hightlightStatus: Array<boolean> = [];

Declare local variable in the template associated with ngFor:

<ul>
   <li [attr.data-selected]="false" 
       (click)="hightlightStatus[i]=!hightlightStatus[i]" 
       [class.highlight]="hightlightStatus[i]" 
       *ngFor="let item of items, let i = index"> 
       {{item}} 
   </li>
</ul>
Sign up to request clarification or add additional context in comments.

2 Comments

This doesn't quite work for me but I believe you are correct. Probably has to do with plunker and my version of angular
Sorry, forgot to mention. Your code looks like Angular 2 beta (#item of items, # was used in beta). Mine - Angular 2 RC1
14

If I am understanding the question properly, I believe you can also use the render from angular2 to get a similar code to your example code. For my own project I did the following:

In my template I have:

<li role="presentation" (click)="userTypeSelect($event)" ><a href="#">Local</a></li>

In my component I then have:

import {Renderer} from '@angular/core';
//other imports

export class SignupComponent implements OnInit {

      constructor(private render:Renderer) { }

      userTypeSelect(event:any){
        event.preventDefault()
        this.render.setElementClass(event.target,"active",false);
      }

}

It is worth noting though that I am not using this for a list of items, however I believe it should still work.

Reference to the Renderer: Renderer Api Docs

1 Comment

in my case it didnt work. so i had to use setElementAttribute. let oldClasses = event.target.getAttribute('class'); this.renderer.setElementAttribute(event.target, "class", oldClasses + ' selected');
9

There are many ways to achieve this, and all are very simple.

Examples:

<li *ngFor="let n of list" (click)="select(n)" [ngClass]="{active: isActive(n)}">
  <a>{{n}}</a>
 </li>

 select(item) {
      this.selected = item; 
  };
  isActive(item) {
      return this.selected === item;
  };

Only using html

<li *ngFor="let n of list" [class.active]="clicked === n" 
         (click)="clicked = n">
       <a>{{n}}</a>
    </li>

Add class on click and remove if we click on the same

select(item) {
   this.selected = (this.selected === item ? null : item); 
};

Only using html

<li *ngFor="let n of list" [class.active]="clicked === n" 
       (click)="clicked = (clicked === n ? null :n)">
     <a>{{n}}</a>
   </li>

More info

Comments

2

By your question title, you want to add a new class to the li when it's clicked, right?

If that's it, then it can be simple like this:

 <ul>
   <li (click)="highlightItem($event)" *ngFor="let item of items">
     {{item}}
   </li>
 </ul>

export class HelloComponent {
  public items: string = ['Apple', 'Banana', 'Pear', 'Grapes', 'Watermelon'];

  public highlightItem(event) {
    if (! event.target.classList.contains('highlighted')) {
      event.target.classList.add('highlighted');
    }
  }
}

Comments

-1

It May help you

export class ContactComponent implements OnInit {

  values:Object[];


  ngOnInit() {
    this.values=[{name:'Alex',done:false},{name:'Jon',done:false}];
  }

  completed(i:number){
    if(this.values[i])
      this.values[i]['done']=!this.values[i]['done'];
  }

}

HTML:

<ul>
    <li *ngFor="let v of values;let i='index'" 
        (click)='completed(i)'
        [class.checked]="v.done" 
        >       
        {{v.name}}<span class="close">×</span>
    </li>
</ul>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.