How to toggle CSS class in Angular2/Typescript to mimic radio buttons behavior

Is there a way to create a radio button group using UL and LI elements in Angular2 and Typescript? The goal is to have all the anchors function like a radio button group where only one can be selected at a time. The selected anchor should remain "clicked" until another anchor is selected, providing the user with visual feedback.

Here is a Plunker example

I'm new to Angular2 and Typescript, so I'm unsure if there's a built-in feature in Angular that can handle this functionality. In jQuery/JS, I would add a class to each anchor for easy selection, remove the clicked class from all anchors when a new one is clicked, and then add the clicked class to the newly selected anchor. Angular's [routerLink] can take care of the routing part.

The current markup is designed with a jQuery solution in mind because I haven't found a way to remove a CSS class directly in Typescript. While I could control styles through interpolation like [style.color], it would require storing style values for each anchor individually. There must be a simpler approach!

<md-sidenav #start mode="over" class="sideDrawer">
  <ul>
    <li><a href="#" class="anchor" id="a11" (click)="sideNavAlert($event)">anchor 1.1</a></li>
    <li><a href="#" class="anchor" id="a12" (click)="sideNavAlert($event)">anchor 1.2</a></li>
    <li><a href="#" class="anchor" id="a13" (click)="sideNavAlert($event)">anchor 1.3</a></li>
  </ul>
  <ul>
    <li><a href="#" class="anchor" id="a21" (click)="sideNavAlert($event)">anchor 2.1</a></li>
    <li><a href="#" class="anchor" id="a22" (click)="sideNavAlert($event)">anchor 2.2</a></li>
    <li><a href="#" class="anchor" id="a23" (click)="sideNavAlert($event)">anchor 2.3</a></li>
  </ul>
  <ul>
    <li><a href="#" class="anchor" id="a31" (click)="sideNavAlert($event)">anchor 3.1</a></li>
    <li><a href="#" class="anchor" id="a32" (click)="sideNavAlert($event)">anchor 3.2</a></li>
    <li><a href="#" class="anchor" id="a33" (click)="sideNavAlert($event)">anchor 3.3</a></li>
  </ul>
</md-sidenav>

Answer №1

Achieving this with Angular 2 is a smooth process. Simply utilize the [ngClass] binding as shown below:

To implement this in your app.component.html, make the following updates:

 <md-sidenav #start mode="over" class="sideDrawer">
      <ul>
        <li><a href="#" [ngClass]="setClasses('a11')" id="a11" (click)="sideNavAlert($event)">anchor 1.1</a></li>
        <li><a href="#" [ngClass]="setClasses('a12')" id="a12" (click)="sideNavAlert($event)">anchor 1.2</a></li>
        <li><a href="#" [ngClass]="setClasses('a13')" id="a13" (click)="sideNavAlert($event)">anchor 1.3</a></li>
      </ul>
      <ul>
        <li><a href="#" [ngClass]="setClasses('a21')" id="a21" (click)="sideNavAlert($event)">anchor 2.1</a></li>
        <li><a href="#" [ngClass]="setClasses('a22')" id="a22" (click)="sideNavAlert($event)">anchor 2.2</a></li>
        <li><a href="#" [ngClass]="setClasses('a23')" id="a23" (click)="sideNavAlert($event)">anchor 2.3</a></li>
      </ul>
      <ul>
        <li><a href="#" [ngClass]="setClasses('a31')" id="a31" (click)="sideNavAlert($event)">anchor 3.1</a></li>
        <li><a href="#" [ngClass]="setClasses('a32')" id="a32" (click)="sideNavAlert($event)">anchor 3.2</a></li>
        <li><a href="#" [ngClass]="setClasses('a33')" id="a33" (click)="sideNavAlert($event)">anchor 3.3</a></li>
      </ul>
    </md-sidenav>

Subsequently, in the app.component.ts, add the following:

export class AppComponent {

    private selectedAnchorId: string;
    sideNavAlert(e): void {
      this.selectedAnchorId = e.currentTarget.id;
    }

    setClasses(elementId){
      return {
        anchor: true,
        anchorClicked: this.selectedAnchorId === elementId
      };
    }
}

Answer №2

If you are working with Angular 2, one way to add classes to your element is by using the syntax

[class.myclass]="boolean expression"
. When the boolean expression evaluates to true, the class myclass will be applied to the element. You can use any valid javascript expression, including method calls, as the condition.

Another option is to apply multiple classes at once using the syntax:

[class]="myclass1 myclass2 myclass3"
. In this case, you provide a string that includes all the class names you want to add to the element.

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

Tips for enhancing express.Request using tsserver and JSDoc

Recently, I have been utilizing tsserver with JSDoc in vim while working on a JavaScript project. Unfortunately, I've encountered an issue that needs resolving: /** @type {import('express').Handler} */ function requireUser(req, res, next) { ...

What are the ways in which Angular can offer assistance to Internet Explorer 9?

The news is out - the Angular team has just announced their support for Internet Explorer 9! This revelation has left me wondering, how is it even possible? Currently, I am an avid user of AngularJS and have dedicated time to studying its ins and outs. Fr ...

Using jQuery to temporarily disable a div element

I need to implement a timer in a div that will disable it for a specific duration, such as 3 seconds. Here is the HTML code snippet: <div class="answ-container" align="center"> <div class="c_answer" id="1316" name="1" data-rcat-no="1"> ...

Automatically Update Woocommerce Checkout with Ajax when Item is Removed or Quantity is Altered

Is there a way to update the checkout page using ajax when an item is removed or when the quantity selector is clicked? The code in my /checkout/order-review.php file does not use the default WooCommerce table. Here is the code snippet: <?php defin ...

Form submission issue persists despite ajax partial rendering

Currently, I'm working on a website that allows users to express their wishes. My goal is to make it as user-friendly as possible by allowing them to create wishes from any page on the site. To achieve this, I am considering using a jQuery/Ajax approa ...

Collect form input data containing a binary image and showcase it in a view using webapi

I am currently working on a webapi project using MVC architecture. The project involves converting a jpg image to binary data, sending it to a SQL server, and then retrieving the form data along with the image back as a jpg for display on the view. Althoug ...

unable to successfully execute jQuery popup close functionality

I have a button on my mobile site that I want to function as follows: Upon clicking the button, a popup should appear with text and an OK button. When the OK button is clicked, the popup should disappear without affecting the page. My code for this functi ...

Incorporating jQuery to convert text into clickable links

Here is the situation: <div class="myclass"> Lorem ipsum dolor sit amet, http://example.com consectetuer adipiscing elit. </div> I am looking for a jQuery function that can be executed after the dom ready event. This function should locat ...

A JavaScript variable... cannot access

Can anybody explain to me the reason behind this reference not functioning properly? let linkId = $(this).attr("data-id"); //retrieve the id data when a tag is clicked $(".wrapper").find("section[id=linkId]").css({"background-color": "red"}); ...

The AJAX call patiently pauses until the preceding request completes

I am attempting to showcase installation progress using AJAX. Here is what my PHP code looks like: if($method == "install"){ $_SESSION['progress']="step 1"; $obj->thisTakesAboutAMinute(); $_SESSION['progress']="step 2"; $o ...

What is the most efficient way to retrieve values from chained deferreds in jQuery?

I'm attempting to track the result of a function call: $('#button').on('click', function(){ console.log( getMessage(3) ); // I want this to wait until the ajax-related operations are completed below }); The ajaxFetch() functio ...

Is it possible to pass a prop from a parent container to children without knowing their identities?

I am currently working on a collapsible container component that can be reused for different sections of a form to display fields or a summary. Each container would include a Form object passed as a child. Here is the basic structure of my code: function C ...

Creating a TypeScript definition file that exports a class after instantiation

Currently, I am struggling with a specific typescript definition that is not functioning as expected: mapping.ts class Mapping { // } var mapping = new Mapping(); export = mapping; This setup allows for the following usage: import _mapping = require(&ap ...

The system is unable to process the property 'items' due to a null value

When trying to access the properties of ShoppingCart, an error is encountered stating that Property item does not exist on type {}. The mistake made in the code is unclear and difficult to identify. shopping-cart.ts import { ShoppingCartItem } from &apos ...

Establish a timeout period when using the hover function

My dynamically loaded content requires a specific method of invocation due to its unique nature. While the process runs smoothly without using a setTimeout, is there any way to introduce a 0.25 second delay in this scenario? Check out this fiddle for ref ...

Leveraging Angular, ExpressJS, and NodeJS to enable users to download a text file by simply clicking a

My goal is to incorporate a download button that allows users to download a document from my node.js server. Behold the stylish download button: https://i.sstatic.net/s4CjS.png My tech stack includes Angular for the front-end and node.js along with exp ...

Prevent a specific directory from being compiled in MSBuild using Typescript

I have a unique ASP.NET MVC / Angular2 project that utilizes MSBuild for compiling my Typescript files. Within the project, there is the complete Angular2 source code along with its NodeJS dependencies, in addition to my own Angular2 code (app.ts, etc.). ...

Having trouble locating a nested component through multiple ng-content in Angular 8?

Currently, I am encountering an issue while attempting to locate components nested within sub child components. To illustrate what I am aiming for, here is an example: import { Component, OnInit, ContentChildren, ElementRef, QueryList } from '@angul ...

Look for identical values within a nested array

My data consists of a nested array where each element has a property called name, which can only be either A or B. I need to compare all elements and determine if they are all either A or B. Here is an example of the input: [ { "arr": { "teach ...

Organize routes into distinct modules in Angular 6

Currently grappling with routing in my Angular 6 application. Wondering if the structure I have in mind is feasible. Here's what it looks like: The App module contains the main routing with a parent route defining the layout: const routes: Routes = ...