How to apply ngClass to only one table head

Viewed 118

HTML

<th>Car Name <i (click)="sortData('carName')" [ngClass]="custom" class="fa sort-icon"></i></th>

<th>Car Status <i (click)="sortData('carStatus')" [ngClass]="custom" class="fa sort-icon"></i></th>

TS

sortData(name) {
  this.pipeFlag = !this.pipeFlag;
  this.custom = (this.pipeFlag === true) ? 'fa-arrow-down' : 'fa-arrow-up';
}

I am trying to apply a font awesome class to table heads on click but it gets applied to both table heads. How do i apply it only to the table head that I click?

3 Answers

You are binding both table heads' ngClasses to the same variable: [ngClass]="custom", so when custom changes, both table heads will be updated.

You could create an object that would hold classes for different elements, like this:

public custom = {
  carName: 'fa-arrow-down'
  carStatus: 'fa-arrow-down'
};

Then your sortData method will look as follows:

sortData(name) {
  this.pipeFlag = !this.pipeFlag;
  this.custom[name] = (this.pipeFlag === true) ? 'fa-arrow-down' : 'fa-arrow-up';
}

And HTML:

<th>Car Name <i (click)="sortData('carName')" [ngClass]="custom['carName']" class="fa sort-icon"></i></th>
<th>Car Status <i (click)="sortData('carStatus')" [ngClass]="custom['carStatus']" class="fa sort-icon"></i></th>

You just two boolean fagging whethe the class is one or the other.

<th>
    Car Name 
    <i (click)="sortData('carName')" class="fa sort-icon" 
     [ngClass]="{
          'fa-arrow-down': !iconClasses.carName,
          'fa-arrow-up': iconClasses.carName
     }"></i>
</th>
<!-- The other th tag analogue but pointing to iconClasses.carStatus -->

Let's define what iconClasses is.

interface IconClasses {
    carName: boolean;
    carStatus: boolean;
}

So, iconClasses will store the actual flag per icon.

// Initialize iconClasses in your Component class.
public iconClasses: IconClasses = {
    carName: false;
    carStatus: false;
}

// ...

sortData = icon => {
    const flag = this.iconClasses[icon];
    this.iconClasses[icon] = !flag;
}

By changing the flag, Angular keeps a tracking on the actual value so the class will be swapped under the scenes.

There is too many ways to achieve the same behavior.
Here's how I would do it.

By the way, [ngClass] has lots of overwrites, one of them is the one I used which expects an object where every key is the class name and the value is a boolean indication where or not is applied.
Here's some extra information from the documentation.

Hope it helps.

This is because you are using same property for both th you can do below 2 things

1) apply ngClass to only Car Name th if you want class to apply in first th only

or

2) Simply Call function in ngClass and pass a flag like

(click)="sortData('name')" // for name
(click)="sortData('status')" // for status

and in function do something like this.

sortData(type) {
  this.pipeFlag = !this.pipeFlag;
  if(type === 'name'){
   this.custom =  (this.pipeFlag === true) ? 'fa-arrow-down' : 'fa-arrow-up';
  } else if(type === 'status'){
    // status related stuff
  } 
}
Related