Utilize ngClass for every individual section

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

https://i.sstatic.net/hxJQr.png

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

Error encountered in React component: TypeScript TS2339 states that the property 'xyz' is not found on type 'IntrinsicAttributes...'

I am attempting to develop a straightforward React component that can accept any properties. The syntax below using any is causing issues (unexpected token just before <): export class ValidatedInput extends React.Component<any, any> {...} The p ...

Steps for sending data from Angular2 or Angular4 to a Node.js server and saving it in a MySQL database:1. In your

I've scoured the depths of the internet on Google but have come up empty-handed in finding a reliable working example. Any assistance would be greatly appreciated as I am relatively new to Angular2 (angular4). My goal is to have my angular2 applicati ...

Observer function simulated by SinonStub

I am currently testing express middleware using sinon.js My goal is to verify that it sends a specific JSON response and prevents the request from moving on to the next middleware or request handler. const middleware = (req: Request, res: Response, nex ...

Arrangement of items in Angular 2 array

Received a JSON response structured like this JSON response "Terms": [ { "Help": "Terms", "EventType": "Success", "Srno": 1, "Heading": "Discount Condition", "T ...

I am interested in creating a design where two DIVs are layered on top of each other with one having transparency, allowing visibility through to the background DIV. This can be achieved using a combination of

Looking to enhance the visual appeal of my website, I decided to incorporate a background image within a div. To add more depth and creativity, I am now striving to overlay a semi-transparent black box on top of the image. This overlay will not only allo ...

What is the best way to implement switchMap when dealing with a login form submission?

Is there a better way to prevent multiple submissions of a login form using the switchMap operator? I've attempted to utilize subjects without success. Below is my current code. import { Subject } from 'rxjs'; import { Component, Output } ...

Looking for a way to add a CSS effect that reveals another image or text when hovering over an image?

My company's website features 10 country flags that, when clicked, display the entire site in that country's language for the user's session. However, I want to take it a step further and have a small image of the respective country appear w ...

Neglecting to review the CSS - embracing ejs layouts in Express

I am encountering an issue with the express ejs layouts where only the mainPage is able to read the CSS, while the other pages are unable to do so (even though the HTML reads it). Additionally, if I want to use another layout such as "layout2.ejs", what s ...

Is the second parameter of the function being used as a condition?

Why is it necessary to validate the helpText argument within the function to be non-equative to null when its ID is linked with the span tag? The functions task is to set and clear help messages in the form field using built-in CSS classes. <input id ...

Integrating Angular with Django using the REST framework

Is there a way to serve Angular using only a Django server without the need for separate servers? I have created a frontend application with Angular 6 and backend with DRF, currently running the django server in the backend and using ng serve command for ...

What is the best way to eliminate unwanted white space at the top of the page?

I'm new to web development and I'm exploring the concept of white space at the top of a webpage. Here is a snippet of my code: HTML: <div> <p>lorem ipsum</P> </div> CSS: div { background-color: black; } I attem ...

Struggling to concentrate on the branding

I've been using materializecss for some time now and recently encountered an issue while trying to navigate my website using keyboard tabbing. The checkbox in materializecss is a custom CSS checkbox, but when I set the tabindex for the label of the c ...

Bypass URL Routing for a specific route in Angular 8 and Apache

I currently have two Angular applications: the FrontEnd and Admin. Both of these are hosted on cPanel behind an Apache server. The website setup is as follows: mydomain.com/ ----> Frontend Angular Application mydomain.com/admin ----> Admin Angular ...

Issue with CSS transition bug in Offcanvas on Android version 4.1.x

I am attempting to develop an offcanvas menu similar to the one featured in the Google Plus app. Currently, my code functions properly on most devices (android/ios) and browsers (ff, chrome, IE8+). The only issue I am encountering is on a Samsung Galaxy ...

Exploring the intricacies of defining Vue component props in TypeScript using Vue.extend()

Here is a simple example to illustrate my question When I directly define my props inside the component, everything works fine <script lang="ts"> import Vue, { PropType } from "vue"; export default Vue.extend({ props: { col ...

Struggling to format boxes or display images on your WordPress website?

When working on this website, I encountered an issue with adding links to Google+ and Facebook. Despite my efforts to style the div boxes using CSS, I was unsuccessful. I also attempted to insert images using an img tag, but the pictures did not load even ...

Displaying a child component as a standalone page rather than integrating it within the parent component's body

I'm currently working on implementing nested navigation in my website, but I am facing challenges with loading the child component without the need to include a router-outlet in the parent component. This setup is causing the child component's co ...

When the next button is clicked, the button content disappears

I am struggling with a problem involving two buttons that store tables. The issue is, I want the table to disappear when the second button is clicked and show the contents of the second button immediately after clicking it once, rather than having to click ...

What are the steps to fix the error stating that 'loginError.data' is an unknown type?

Recently delving into typescript, I decided to test the waters with nextjs, rtk query, and antd. However, while attempting to access error within useLoginMutation using the property error.data.message, it was flagged as type unknown. To tackle this issue, ...

Steps to validate the execution of the ngCopy function in an Angular 6 unit test

While working on one of my angular components, I have implemented the ngCopy module to enable text copying to clipboard. The code snippet below showcases how I have used this module: import {Component, Input, OnInit} from '@angular/core'; import ...