简体   繁体   中英

Add class dynamically to td on click and toggle and remove when other td is clicked in angular/typescript

I am working in angular app where I am working on COVID 19 app.I have table with 5 columns

    1. STATE
    1. CONFIRMED
    1. ACTIVE
    1. RECOVERED
    1. DECEASED

Here is my stack blitz link stack blitz link .

Also here is the reference of my expectation Expectation .

On clicking any column I am sorting my whole table data in ascending or descending order and displaying an up arrow for ascending and down arrow for descending.

My problem is when I click on any column all the arrows on all columns get changed where as I only want to change arrow for the column I have clicked and hide arrows for other columns. Also initially when page loads my arrow should not get visible ,instead they should be only visible when i click on any column.

Here is my code

component.html

               <tr>
                    <th (click)="sortAscending(sortedDataBasedOnDate)" class="sticky state-heading">
                        <div class="heading-content"><abbr title="State">State/UT</abbr>
                            <div [ngClass]="showarrow  ? 'down-arrow' : 'up-arrow'"></div>
                        </div>
                    </th>

                    <th (click)="sortByMaxCases(sortedDataBasedOnDate)" class="sticky">
                        <div class="heading-content"><abbr class="" title="Confirmed">Confirmed</abbr>
                            <div [ngClass]="showarrow  ? 'down-arrow' : 'up-arrow'"></div>
                        </div>
                    </th>

                    <th (click)="sortByMaxActive(sortedDataBasedOnDate)" class="sticky">
                        <div class="heading-content"><abbr class="" title="Active">Active</abbr>
                            <div [ngClass]="showarrow  ? 'down-arrow' : 'up-arrow'"></div>
                        </div>
                    </th>

                    <th (click)="sortByMaxRecovered(sortedDataBasedOnDate)" class="sticky">
                        <div class="heading-content"><abbr class="" title="Recovered">Recovered</abbr>
                            <div></div>
                            <div [ngClass]="showarrow  ? 'down-arrow' : 'up-arrow'"></div>
                        </div>
                    </th>

                    <th (click)="sortByMaxDeath(sortedDataBasedOnDate)" class="sticky">
                        <div class="heading-content"><abbr class="" title="Deaths">Deceased</abbr>
                            <div [ngClass]="showarrow  ? 'down-arrow' : 'up-arrow'"></div>
                        </div>
                    </th>
                </tr>

Component.ts

 showarrow=false


 sortAscending(data) {
    this.isAscendingSort = !this.isAscendingSort;
    this.showarrow=true                                 // setting here
    data.forEach(item => item.statewise.sort(function (a, b) {
      if (b.state < a.state) {
        return -1;
      }
      if (b.state > a.state) {
        return 1;
      }
      return 0;
    }))
    this.calculateDiff(this.sortedDataBasedOnDate)

    if (!this.isAscendingSort) {
    this.showarrow=!this.showarrow           // for descending toggling class here
      let a = data.forEach(item => item.statewise.sort(function (a, b) {
        if (a.state < b.state) {
          return -1;
        }
        if (a.state > b.state) {
          return 1;
        }
        return 0;
      }))
      this.calculateDiff(this.sortedDataBasedOnDate)
    }
  }

Also I have tried this approach for initially hide arrows on page load but it have same problem that if I click on any column arrow will appear on all column.

Component.html

   <div class="heading-content"><abbr title="State">State/UT</abbr>
        <div [ngClass]="{'down-arrow':showarrowdesc , 'up-arrow' : 
         showarrowasc,'hide':hide}"></div>

    </div>

Component.ts

 showarrowasc=false
 showarrowdesc=false
 hide=true

 sortAscending(data) {
    this.isAscendingSort = !this.isAscendingSort;
    this.showarrowasc=!this.showarrowasc
    this.showarrowdesc=false
    
    data.forEach(item => item.statewise.sort(function (a, b) {
      if (b.state < a.state) {
        return -1;
      }
      if (b.state > a.state) {
        return 1;
      }
      return 0;
    }))
    this.calculateDiff(this.sortedDataBasedOnDate)

    if (!this.isAscendingSort) {
    
    this.showarrowdesc=!this.showarrowdesc;
    this.showarrowasc=false
      let a = data.forEach(item => item.statewise.sort(function (a, b) {
        if (a.state < b.state) {
          return -1;
        }
        if (a.state > b.state) {
          return 1;
        }
        return 0;
      }))
      this.calculateDiff(this.sortedDataBasedOnDate)
    }
  }

Any help will be great.

I guess you are cutting your provided code as I cannot see sortByMaxCases() (and the others except for sortAscending()) which you are calling from your template.

Then, from what I can see here it seems that you are toggling all columns with the same boolean: showarrow.

To overcome this you could for example create an object that holds multiple properties, one for each column, like so:

const showArrows = {
    confirmed: false,
    active: false
}

Add all the other columns that you have as well and define one as true as an initial sorting.

Then in your template reference that object as follows:

<th (click)="sortAscending(sortedDataBasedOnDate)" class="sticky state-heading">
    <div class="heading-content"><abbr title="State">Confirmed</abbr>
        <div [ngClass]="showArray.confirmed ? 'down-arrow' : 'up-arrow'"></div>
    </div>
</th>

As an example for the confirmed column.

Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM