Wednesday 12 April 2017

Conditionally add class to an element on click - angular

AngularngClassConditionally add class

Here I am going to discuss about adding a class to an active element. For example if we click on a link or dynamic menu we need to highlight that with a color. In this article we will be discussing the same in different scenarios.

  1. Add class to an element on click and remove on click of other item and highlight the current one. (With js and With out js)
  2. Add class to an element on click and remove if we click again on the same.(With js and With out js)

Let us check one by one.

1. Add class to an element on click and remove on click of other item and highlight the current one.


Let us check how we can achieve this by using very less code.

Html


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

Component


export class App {
  list:any;
  selected :any;
  constructor() {
    this.list = [
       'Read about Angular',
       'Read about knockout',
       'Read about backbone',
       'Read about jquery',
       'Read about javascript'
    ]; 
  }
  select(item) {
      this.selected = item; 
  };
  isActive(item) {
      return this.selected === item;
  };

}

Here I have used *ngFor to loop and angular click method for click event.

Dont forget to add below css


.active a{color:red;}

Add class to an element on click, by only using html code

The above one you can achieve with out using any js code it self. It required some changes in the html. Please see below code for that.


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

2. Add class to an element on click and remove if we click again on the same.


Now let us check another scenario. We will add class and remove if user clicks again on the same item. For achieving this functionality you can follow above same code except one small change in one method. See below updated method.


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

Using this approach you can easily find out user is clicking on same item again or not and you can write you're on logic also in this scenario. See the below code for more info.


 select(item) {
  if(item === this.selected)
   {
      this.selected = null;
      //your logic
    }else
    {
      this.selected = item;
      //your logic
     }
 };

Add class to an element on click and remove on same click, by only using html code

The above one you can achieve with out using any js code it self. It required some changes in the html. Please see below code for that.


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

I didn't add all examples in the plunker, but you can always edit and play on that.

I have explained about 5 different ways for adding a class dynamically using Angular, please check those here:- 5 different ways for conditionally adding class - Angular.

Here we have discussed about adding a class to an item on click.

Angular 2+ngClassConditionally add class

Related Info

1. Date filtering and formatting using pipe in Angular 2

2. Simple search using pipe in angular 2

3. Angular 2 toggle button | Angular 2 collapsible panel

14 comments :

  1. Hi,
    This is amazing. I applied this to my thumbnails in Angular 2, so whenever clicked the background colour changes.
    My problem is that the backgroud changes only while I am pressing on the mouse. As soon as I release the mouse, the thumbnail is not active anymore. So, do you have any suggestions for that?

    ReplyDelete
    Replies
    1. I am not sure what is happening in your case. Add important to your css and try once. Difficult to judge with out seeing the code.

      Delete
  2. Hi ABC.com

    saw ur post and implemented ur code in my project:
    Add class to an element on click, by only using html code on tr like somewhat like this
    .
    .
    .
    .
    .
    --tr-- *ngFor="let n of list" [class.active]="clicked === n" (click)="clicked = n"
    --td--Some data....--/td--
    --td--Some data....--/td--
    --td--Modal popup button--/td--
    --td--Some data....--/td--
    --tr--

    Now when i click on modal popup active class added to the parent tr!
    How to prevent this from happening ?
    DdotRANOLIA92@GMAILdotCOM

    ReplyDelete
    Replies
    1. Try to add e.stopPropagation(); on Model popup button click.

      Delete
  3. One of the easiest way to do this is that, just invoke the method after getting the result. For example ,in my above example case..
    Call this method after getting result
    this.select(this.list[0]);

    In your case, might be something like this
    this.setCurrencyActive(this.currencySelected);

    ReplyDelete
  4. This is very good exampler but if 2 names are same both are clicked, if at arrays you have names, id and other things the best thing is selected to be like this.selected = item.id or something like this. But this code helped me so much.
    Best Regards
    You are very very good

    ReplyDelete
  5. man you are great,thanks

    ReplyDelete
  6. ngOnInit() {
    this.blogService.getPublished().subscribe(blogs => (this.blogs = blogs));
    this.categoryService
    .getCategories()
    .subscribe(categories => ( this.categories = categories, this.select(this.categories[0])) );
    }
    I'm try by this way, but nothing happens.

    ReplyDelete
  7. This is very useful code. I've applied this code to navbar where added active class if item is selected.

    But now I want if other item is clicked, previous active class will be removed and add to selected item only. Can you please help me to achieve this?

    onItemSelected(item) { this.selectedItem = item; }
    isActive(item) {return this.selectedItem === item }


    --li *ngFor="let item of items"
    --a (click)="onItemSelected(item)" [ngClass]="{'active': isActive(item)}"

    ReplyDelete
  8. i have done this and its working for me. But when i refresh page the css removed. Any way to persist or add class as per url in browser?

    ReplyDelete
    Replies
    1. You can read the URl and update the logic https://www.angulartutorial.net/2020/03/how-to-get-parameter-on-angular-route.html

      Delete
  9. Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon. Big thanks for the useful info. https://catcherrors.com/repos/facebook/react

    ReplyDelete