Changing icons within an ngFor loop in Angular 2

Looking for a solution: How can I toggle icons using ngFor?

Situation: I am using *ngFor to iterate through an array and display category names. When a day is clicked, I want to open an accordion and show category details (which I have already managed). Once the accordion is opened, I need to switch the fa-plus icon with fa-minus and vice versa, but only for the clicked day.

Any effective way to achieve this?

this.categoryList = [
{type: 'space', name: 'Space'},
{type: 'energy', name: 'Energy'},
{type: 'comfort', name: 'Comfort'},
{type: 'maintenance', name: 'Maintenance'},
{type: 'reporting', name: 'Reporting'}
];

HTML

<div class="{{category.type}}" *ngFor="let category of categoryList">
    <div data-toggle="collapse" [attr.href]="'#'+'category-'+category.type">
    <div class="title {{category.name}}">{{category.name}}</div>
    <div>
        <i class="fa fa-plus"></i> //needs to toggle between plus and minus
                <i class="fa fa-minus"></i> //needs to toggle between plus and minus
    </div>
    </div>

    <div class="collapse" id="category-{{category.type}}">
        //details
    </div>
</div>

Answer №1

If my interpretation is correct, you only need one <i> element on the page instead of having two:

template:

<div *ngFor="let day of daysInAWeek; let i = index">
    <div>{{day}}</div>
    <div>
        <i class="fa" [ngClass]="toggle[i] ? 'fa-plus': 'fa-minus'" aria-hidden="true"></i>
    </div>
    <div class="details">Today is {{day}}</div>
    <button (click)="toggle[i] = !toggle[i]">Toggle</button>
</div>

ts:

daysInAWeek: string[] = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']; 
toggle = {};

By toggling the classes on that single element to either fa-plus or fa-minus, you can achieve the desired effect.

You can apply (click)="toggle[i] = !toggle[i] to any HTML element within your *ngFor template to trigger the toggle action on click for the corresponding <i> element.

Answer №2

1) It is important to have a variable that keeps track of the currently selected day.

public SelectedDay:string = null;

2) When a day is clicked, update the selected day value,

<div (click)="SelectedDay=day">{{day}}</div>

3) Use *ngIf or hidden to check if the selected day matches the current day in the loop

<i class="fa fa-plus" *ngIf="SelectedDay!=day" aria-hidden="true"></i>
  <i class="fa fa-minus" *ngIf="SelectedDay==day" aria-hidden="true"></i>

Your final HTML structure should resemble this -

<div *ngFor="let day of daysInAWeek">
<div (click)="SelectedDay=day">{{day}}</div>
 <div>
   <i class="fa fa-plus" *ngIf="SelectedDay!=day" aria-hidden="true"></i>
   <i class="fa fa-minus" *ngIf="SelectedDay==day" aria-hidden="true"></i>
 </div>
<div class="details">Today is {{day}}</div>
</div>

Implementing these steps should achieve the desired functionality.

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

How to include a cancel button within a tab component using Angular Material

I recently implemented a tab component with custom label templates. You can view the code and see how it works in this StackBlitz project. My question is, how can I add a cancel button to the top-right corner of the tabs? I don't need the button to do ...

What is the best way to utilize a single npm module in multiple TypeScript files?

Question: I keep encountering the error message "error TS2451: Cannot redeclare block-scoped variable 'os'" when I try to import the same npm module in multiple TypeScript files and run the TypeScript compiler tsc. Here is an overview of my proj ...

Uncertainty surrounding refinement in Typescript

I've been diving into the book Programming TypeScript, and I'm currently stuck on understanding the concept of refinement as shown in this example: type UserTextEvent = { value: string; target: HTMLInputElement }; type UserMouseEvent = { value: [ ...

What is the best way to output data to the console from an observable subscription?

I was working with a simple function that is part of a service and returns an observable containing an object: private someData; getDataStream(): Observable<any> { return Observable.of(this.someData); } I decided to subscribe to this funct ...

Issue encountered with UglifyJs - Unexpected token: title (Subject)

My attempt to deploy my initial Angular application is not going smoothly. The build process fails and the error message I'm encountering states: ERROR in vendor.809dd4effe018f6b3d20.bundle.js from UglifyJs Unexpected token: name (Subject) [vendo ...

What is the process of programmatically sorting a column in a Material UI DataGrid?

Hey there! I'm currently working on a DataGrid that has a column with a custom header, specifically a Select option. My goal is to have the column sorted in descending order every time a user selects an option from the dropdown menu. renderHeader: (pa ...

Angular 8 combined with Mmenu light JS

Looking for guidance on integrating the Mmenu light JS plugin into an Angular 8 project. Wondering where to incorporate the 'mmenu-light.js' code. Any insights or advice would be greatly appreciated. Thank you! ...

How to retrieve the value of a nested checkbox in Angular using dynamic methods

I successfully developed dynamic nested checkboxes in Angular and now I am looking to retrieve the values of the selected checkboxes. However, I encountered an issue with the JSON structure needed to implement this functionality. https://i.stack.imgur.com ...

Come up with a multi-colored theme using angular material2 that features a palette of more than three

When customizing a theme for angular material2, it's mentioned that you can specify a primary, accent, warn foreground, and background color. However, the process for creating a theme only allows for 3 colors/palettes to be set: $candy-app-theme: ma ...

Using TypeScript to import npm modules that are scoped but do not have the scope name included

We currently have private NPM packages that are stored in npmjs' private repository. Let's say scope name : @scope private package name: private-package When we install this specific NPM package using npm install @scope/private-package It ge ...

Angular material stepper displaying incorrectly

Here is the HTML code I used for creating an Angular Material stepper: <mat-horizontal-stepper class="stepper"> <mat-step label="Basic" state="cloud_download"> Step 1 <button mat-button matSteppe ...

Exploring the benefits of event subscription nesting

One feature I'm currently utilizing is the Angular dragula drag and drop functionality, which enables me to effortlessly move around Bootstrap cards within the view. When an item is "dropped," it triggers the this.dragulaService.drop.subscribe() funct ...

I am attempting to gather user input for an array while also ensuring that duplicate values are being checked

Can someone assist me with the following issue: https://stackblitz.com/edit/duplicates-aas5zs?file=app%2Fapp.component.ts,app%2Fapp.component.html I am having trouble finding duplicate values and displaying them below. Any guidance would be appreciated. I ...

Tips for maintaining knowledge after redirecting to a new page

Building an app using Ionic 4 where I need to display vouchers from a database as images. Each image should act as a link to a details page showing more information about that specific voucher. However, I am struggling to figure out how to keep track of th ...

Angular application featuring scrolling buttons

[Apologies for any language errors] I need to create a scrollable view with scroll buttons, similar to the image below: Specifications: If the list overflows, display right/left buttons. Hide the scroll buttons if there is no overflow. Disable the le ...

How can you line up various form elements, like pickers, in a row using Material UI?

As someone new to material ui, I haven't come across a solution for my specific issue yet. While there are similar questions, none seem to address the problem of aligning different form field types. My observation is that the material ui date picker ...

I am facing an issue with Angular 14 and Webpack 5, where certain unnecessary nodejs modules seem to be hindering me from successfully serving

I have recently started working on a cutting-edge Angular 14 application. My current node version is v14.20.0, and npm version is 8.17.0. Despite my best efforts, I seem to be facing an issue with multiple nodejs dependencies being included in my project ...

Tips for utilizing the index and style attributes when passing them to the Row function in React-Window

Currently, I am attempting to define the index and style parameters passed to the Row function in TypeScript. //https://github.com/bvaughn/react-window import * as React from "react"; import styled from "styled-components"; import { Fi ...

I am unable to access the 'UserName' property in Angular 2 because it is undefined

I have tried multiple solutions, but none of them have helped me solve this issue... I am struggling to identify the problem in my code... HTML CODE :: <input type="text" class="form-control" placeholder="Please Enter Your Username" [(ngModel)]="curr ...

Disabling the use of console.log() in a live environment

In an effort to disable console logs for production environments in my angular application, I implemented the code below. While it successfully suppresses logs in Chrome, IE 11 continues to display them. Here is the snippet from main.ts: if (environment. ...