Tips for updating an Angular renderer's value

I have a challenge with implementing a background color change when clicking on a th element. Currently, it works fine when I click on it, but I would like to make it so that if I click on another th element, the previous one will turn off. However, if I click on the same th again, it should not turn off until I switch to another th. I am working with Angular 8 and my directive code is as follows:

@Directive({
  selector: '[sortColumn]'
})
export class SortDirective implements OnInit {

  @Input() data: any;
  @Input('sortKey') key: any;
  @Input('sortNumber') num: number;
  private toggleSort: boolean = false;

  constructor(private el: ElementRef, private renderer: Renderer) {
  }

  ngOnInit() {
    this.renderer.listen(this.el.nativeElement, 'click', (event) => {
      let parentNode = this.el.nativeElement.parentNode;
      let children = parentNode.children;

      if (this.data && this.key) {
        let sortedData: any = this.sortArray();
      }

      if (this.data && this.num) {
        let sortedData: any = this.sortNums()
      }     
      this.changeTextColor()
    })
  }

  changeTextColor() {
    this.renderer.setElementStyle(this.el.nativeElement,"background-color","green");
    this.toggleSort = !this.toggleSort;
  }
}

Answer №1

Utilizing a service for efficient management...

One approach is registering all directives to a designated service in order to oversee the state of the directives, specifically isActive.

In this demonstration, we showcase a button Directive as an illustration, but the underlying principles can be adapted to suit your requirements:

The managerial service:

  managedDirectives: BtnDirective[] = [];

  addManagedDirective(btn: BtnDirective) {
    this.managedDirectives.push(btn);
  }

  removeManagedDirective(btn: BtnDirective) {
    this.managedDirectives.filter(item => item !== btn);
  }

  activate(btn: BtnDirective) {
    this.managedDirectives.map(item => {
      if(item === btn) {
        item.isActive = true;
      } else {
        item.isActive = false;
      }
    })
  }

The directive:

  @HostBinding('class.is-active')
  isActive: boolean;

  @HostListener('click') onClick() {
    this.managerService.activate(this);
  }

  constructor(
    private managerService: ManagerService
  ) { }

  ngOnInit(): void {
    this.managerService.addManagedDirective(this);
  }

  ngOnDestroy() {
    this.managerService.removeManagedDirective(this);
  }

A comprehensive working example is accessible via: https://stackblitz.com/edit/angular-1gk9ya

This service-based solution operates autonomously from the DOM structure without the necessity of querying DOM elements directly. Embrace the power of Angular over jQuery ;)

Answer №2

One way to handle the styling of a clicked element is to add a specific class to it instead of directly changing its style properties. By assigning a class, you can ensure that only one element has this class at a time and easily manage its appearance.

@Directive({
  selector: '[sortColumn]'
})
export class SortDirective implements OnInit {

  @Input() data: any;
  @Input('sortKey') key: any;
  @Input('sortNumber') num: number;
  private toggleSort: boolean = false;

  constructor(private el: ElementRef, private renderer: Renderer) {
  }

  ngOnInit() {
    this.renderer.listen(this.el.nativeElement, 'click', (event) => {
      let parentNode = this.el.nativeElement.parentNode;
      let children = parentNode.children;

      if (this.data && this.key) {
        let sortedData: any = this.sortArray();
      }

      if (this.data && this.num) {
        let sortedData: any = this.sortNums()
      }     
      this.changeTextColor()
    })
  }

  changeTextColor() {
    let currentlyActiveElement = document.querySelector('.active');
    // Check if there is an active class on another element and remove it
    if(currentlyActiveElement) {
        currentlyActiveElement.classList.toggle('active');
    }


    this.renderer.addClass(this.el.nativeElement,"active");
    this.toggleSort = !this.toggleSort;
  }
}

To style the clicked elements in your CSS:

.active {
    background-color: green;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide on how to navigate to a different page while making a request in ASP.NET

I have a standard asp.net page containing multiple buttons. I would like to add one button labeled Stop Request, which, when clicked, refreshes the page regardless of which other button the user has clicked previously. Here is an example of how I envision ...

Instructions for incorporating animation into the CSS properties of an element as the class is updated using jQuery

The issue: I am facing a challenge with an HTML element that has a class called hidden which hides the element with the css attribute display: none;. When I use JavaScript to remove the class, the element immediately becomes visible again (the original di ...

Ways to retrieve the global state from within the mutation namespace module

Within my state, I have organized two namespace modules: portfolio and stocks. The structure looks like this: export default new Vuex.Store({ modules: { stocks, portfolio } }) The stocks module contains a property called stocks, while the por ...

Arrangement of elements in MongoDB

In my application, there is a list of games, each with a specific position that determines the order in which they are displayed to users (e.g. 1, 2, 3...). Currently, I am using MongoDB to store all the game data. Let's say I have a game with positi ...

Utilize jQuery to retrieve the classes of list elements

I have been using $('#ul li').get() to retrieve all the list elements and store them in an array. Each of these list elements contains specific classes... var i; var listClass = ('#ul li').get(); for(i=0;i<listClass.length;i++){ ...

Tips for utilizing sorting, searching, and pagination features in Bootstrap 5 tables

In my simple table, https://i.sstatic.net/bu1md.png Furthermore, I have integrated Bootstrap 5: <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="15777a ...

Utilizing the power of Ionic Native with AngularJS 1 for Cordova SQLite Integration

I am interested in implementing DeepLinking in my hybrid application using ionic-native. Currently, I have a functioning project with an SQLite database that has been tested on both iOS and Android platforms. However, when I include ionic.native in my app ...

Tips for transferring information from Angular 6 to Node.js

Having recently delved into Angular 6 for the first time, I find myself tasked with sending data to a Node.js server. The code snippet below illustrates my approach within an Angular function: import { Component, OnInit } from '@angular/core'; ...

Loop through a collection of unique identifiers for documents and establish event listeners in Firestore

Within my Vuex store, there is an action designed to retrieve a list of uids for followed users from the current user's Firestore UserDataCollection document. The action then processes each uid to extract data that will be displayed on the UI. While t ...

Error 500: Issue with JQuery AJAX File Upload

Hey there, I'm facing an issue with doing a file upload using JQuery's AJAX feature as I keep getting the error 500. $(function() { $( 'form' ).submit ( function() { $.ajax({ type: &a ...

Using Selenium and Python to scrape text from a continuously refreshing webpage after each scroll

Currently, I am utilizing Selenium/python to automatically scroll down a social media platform and extract posts. At the moment, I am gathering all the text in one go after scrolling a set number of times (see code below), but my objective is to only gathe ...

ReactJS issue: I am unable to display the dropdown menu while looping through an array

Although the title may be confusing, I am facing an issue in my Laravel project that integrates ReactJS on the front end. I am attempting to create a dropdown menu for users to select the status of a project. The statuses and their IDs are retrieved from a ...

NodeJS - Bluebird: implementing a loop with a waiting mechanism for completion

Struggling with a seemingly simple task in my NodeJS and MongoDB project. I've included Bluebird for promises, but need some help. In my code, I have a basic for-loop that generates random names and pushes them into an array: const PlayerGenerator = ...

Tips for refreshing only a portion of a webpage using JavaScript/jQuery

I have two distinct navigational sections on my website. The left column has its own navigation menu, while the right column (main content area) contains a separate set of links: My goal is to click on a link in the left-hand sidebar (such as "Resume", "E ...

Using webpack to group files from the "src" directory into the "public" folder

What is the best way to package all the files within the “src” folder and update the current bundled files in the “Public” folder of a Node.js web application? The structure of my project resembles this example: https://github.com/googlearchive/fr ...

Retrieving JSON data and transforming it into HTML

After reading several examples, I am still struggling with a particular issue. I am receiving a feed from an API that is structured like this: { total:123, id: "1234", results: [ { id: "1234", name: "bobs market", ...

Error: The communication channel abruptly closed before the expected response could be delivered

Before diving into the question, I want to mention that the only reference I could find related to this issue was on this Stack Overflow thread. The problem seemed to be associated with Wappalyzer, but it was reportedly fixed in version 4.0.1. Oddly enough ...

Highlight all the written content within the text box

I'm struggling with a piece of code that is supposed to select all the text inside an input field: <input id="userName" class="form-control" type="text" name="enteredUserName" data-ng-show="vm.userNameDisplayed()" data-ng-model="vm.enteredUs ...

Ajax causing submission of 'undefined' data

I have been utilizing an HTML form to send data to a Google sheet, and it was working perfectly fine. However, when I added Ajax code, the data being sent to the Google sheet always turned out to be "undefined". Removing the code resolved the issue, but it ...

Sending data from Spark to my Angular8 projectLearn how to seamlessly transfer data from your

I am utilizing Spark 2.4.4 and Scala to retrieve data from my MySQL database, and now I am looking to showcase this data in my Angular8 project. Can anyone provide guidance on the process? I have been unable to locate any relevant documentation so far. ...