Utilize ngClass for every individual section

I have completed the implementation of all UI components, which are visually appealing.

Here is the data structure I am using:

public filters = [
        {
            tag: 'Year',
            label: 'year',
            items: [2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020]
        },
        {
            tag: 'Cash On Delivery',
            label: 'cash',
            items: this.truthyFalsy
        },
        {
            tag: 'In stock',
            label: 'stock',
            items: this.truthyFalsy
        }
    ];
    

Below is a snippet of my HTML code:

<div *ngFor="let filter of filters">
        <p ><small>{{filter?.tag}}</small></p>
        <div class="line"></div>
        <div>
            <div class="item" *ngFor="let item of filter?.items">
                <button class="btn" [ngClass]="{'btn-active-1':labelType1 === filter.label  && selectedItem === item }"
                    (click)="select(item,filter?.label)">{{item}}</button>
            </div>
        </div>
    </div>
    

The goal is to make the selected buttons active. Here are the specific requirements:

  1. In the year section, only one button should be active.
  2. In the Cash On Delivery section, only one button should be active.
  3. In the In stock section, only one button should be active.

Each section must have at least one active button using ngClass.

Answer №1

View the live DEMO

By clicking on a button, you can pass the item index and label to distinguish different sections and their buttons.

 /* Create an empty object called selectedItem where we can set key (label)
 and value (index) on each button click. With key (label) and value (index),
 we can identify the selected button of each section */
 selectedItem = {};

The select method toggles the button: if the user clicks on an already selected button, it will be deselected; otherwise, it will become selected.

  select(index, label) {
    if(this.selectedItem[label] === index) {
      delete this.selectedItem[label]
    } else {
      this.selectedItem = {
      ...this.selectedItem,
     [label]: index
   };
  }
}

In the template, all you need to do is pass the index and label from the select method and add a conditional active class by using

[class.btn-active-1]="selectedItem[filter.label] === i"

 <div *ngFor="let filter of filters;">
    <p ><small>{{filter?.tag}}</small></p>
    <div class="line"></div>
    <div>
      <div class="item" *ngFor="let item of filter?.items; let i=index">
        <button class="btn" [class.btn-active-1]="selectedItem[filter.label] === i"
          (click)="select(i, filter?.label)">{{item}}</button>
      </div>
    </div>
  </div>

Answer №2

Check out the demo I put together for you on Stackblitz.

If you want to select items by index and have a default selected item, you can use let i = index. Give it a shot to choose the first item in each group:

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  labelType1: string = "";
  public selectedItem = { year : 0, cash: 0, stock: 0  };
  truthyFalsy: any[] = [true, false];
  public filters = [
    {
      tag: 'Year',
      label: 'year',
      items: [2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020]
    },
    {
      tag: 'Cash On Delivery',
      label: 'cash',
      items: this.truthyFalsy
    },
    {
      tag: 'In stock',
      label: 'stock',
      items: this.truthyFalsy
    }
  ];

  select(index, label){
    this.selectedItem[label] = index;
  }
}
}

app.component.html

<div *ngFor="let filter of filters">
    <p><small>{{filter?.tag}}</small></p>
    <div class="line"></div>
    <div>
        <div class="item" *ngFor="let i=index; let item of filter?.items">
            <button class="btn" [ngClass]="{'btn-active-1': selectedItem[filter.label] === i}" (click)="select(i,filter?.label)">{{item}}</button>
        </div>
    </div>
</div>

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

Implementing asynchronous validation in Angular 2

Recently started working with Angular 2 and encountered an issue while trying to validate an email address from the server This is the form structure I have implemented: this.userform = this._formbuilder.group({ email: ['', [Validators.requir ...

“What is the process of setting a referenced object to null?”

Here is an example of the code I'm working with: ngOnInit{ let p1 : Person = {}; console.log(p1); //Object { } this.setNull<Person>(p1); console.log(p1); //Object { } } private setNull<T>(obj : T){ obj = null; } My objective is to ...

Instead of modifying the selected class, jQuery generates inline styles

Utilizing the following code to dynamically create a class: $("head").append('<style type="text/css"></style>'); var newStyleElement = $("head").children(':last'); newStyleElement.html('.move{transform: translateX(1 ...

Ways to access nested div children without using identifiers

To customize the width of a specific div using jQuery, I need to target the following structure in my HTML code. Although parts of it are generated by a lightbox plugin, the part that sets it apart is the unique class "xxxgallery": <div class="xxxgalle ...

Adding custom TypeScript classes to an Electron project is a straightforward process that allows developers to enhance their

Currently working on a hello world project in Electron and stumbled across the possibility of using Typescript for the Main process, . The provided instructions suggest changing the file extension from index.js to index.ts and updating the package.json fi ...

Ensure chip component (div) dynamically resizes its width to accommodate varying lengths of child text elements

I have a main container with two child elements (a text span and an image svg) created using the Material UI component library. My objective is to dynamically adjust the width of the chip based on the length of the text content inside it, while ensuring a ...

The left border is failing to appear on the Td element

When attempting to add border styling to td elements, the left border is not displaying correctly. This issue seems to vary across different browsers. Here is the HTML code: <table class="table-bordered"> <thead> <tr> ...

Guide on how to show the index value of an array on the console in Angular 2

Is there a way to show the array index value in the console window upon clicking the button inside the carousel component? The console seems to be displaying the index value twice and then redirecting back to the first array index value. Can we make it so ...

forEach was unable to determine the appropriate data types

define function a(param: number): number; define function b(param: string): string; define function c(param: boolean): boolean; type GeneralHooks<H extends (...args: any[]) => any> = [H, Parameters<H>] const obj = { a: [a, [1]] as Gene ...

Enhance your SVG progress circle by simply selecting checkboxes

I have a unique system with 5 checkboxes that act as a To-Do list. When I click on each checkbox, the circle's diameter should progressively fill up in increments of 1/5 until all 5 checkboxes are completed. The order in which the checkboxes are click ...

What are the ideal scenarios for implementing routing in Angular?

As I embarked on developing my inaugural Angular app, I initially implemented routing with unique URLs for each "main" component. However, upon encountering Angular Material and its appealing tab functionality, I was captivated. What are the advantages an ...

The AppModule's CanLoad protector

I recently developed an Angular application using angular-cli and successfully implemented CanLoad guard for my modules. The CanLoad check verifies if the user is logged in before loading a module. My question is, can I apply CanLoad guard to AppModule as ...

rendering google charts using jade template

I am facing an issue while trying to display a google annotated chart on my jade project. I managed to successfully load a pie chart, but I am having trouble rendering a chart that requires the container element size to be explicitly defined. You can find ...

Dealing with multiple validation error messages in Angular Material 2

Working on a form using Angular Material 2, I am implementing a template-driven approach with an email input that requires two validators: required and email. The documentation for the input component (available at https://material.angular.io/components/co ...

What could be the reason my dropdown menu is not appearing on hover?

Currently, I am in the process of developing a menu using angularJS and google app script within a dialog box. I have been referring to this sample code for guidance. Instead of pasting all my code here, I can summarize what I have come up with: var a ...

Create animated changes in height for a mdDialog as elements are shown or hidden

Utilizing Angular Material, I have implemented tabs within an md-dialog. The dialog smoothly adjusts its height based on the content of the active tab during navigation. However, when utilizing an ng-if directive to toggle visibility of content, there is n ...

The error message "SyntaxError: Cannot use import statement outside a module" popped up while working with discord.js, typescript, heroku

// Necessary imports for running the discord bot smoothly import DiscordJS, { TextChannel, Intents, Message, Channel, NewsChannel, ThreadChannel, DiscordAPIError } from 'discord.js' type guildTextBasedChannel = TextChannel | NewsChannel | ThreadC ...

jquery mobile integrated seamlessly between image1 and image2

One issue I'm facing with jquery.mobile is that there seems to be a gap between photo1 and photo2 when displayed on my mobile device. Any suggestions on how to eliminate this space and have the images appear seamlessly next to each other? Thank you in ...

Angular's two-way binding feature does not seem to be updating the value for date

In my Angular - Dotnetcore 2.0 form, users are required to update their demographic information including their birth date. Initially, I was using the following code snippet to display the birthdate: <input id="dateOfBirth" type="date" class="form-cont ...

Choosing all components except for one and its descendants

I am searching for a method to choose all elements except for one specific element and its descendant, which may contain various levels of children/grandchildren or more. What I'm trying to accomplish is something like... $("*").not(".foo, .foo *").b ...