Altering the background color of an individual mat-card component in an Angular application

Here is the representation of my mat-card list in my Angular application:

<div [ngClass]="verticalResultsBarStyle">
  <div class="innerDiv">
    <mat-card [ngClass]="barStyle" *ngFor="let card of obs | async | paginate: { id: 'paginator', itemsPerPage: 10, currentPage: currentPage, totalItems: totalItems }" (click)="highlightCard()">
      <mat-card-header>
        <mat-card-title>{{card[0].title}}</mat-card-title>
        <mat-card-subtitle>{{card[0].subtitle}}</mat-card-subtitle>
      </mat-card-header>
      <mat-card-content>
        <p>{{card[0].info1}}</p>
        <p>{{card[0].info2}}</p>
        <p>{{card[0].info3}}</p>
        <p>{{card[0].info4}}</p>
        <p>{{card[0].info5}}</p>
      </mat-card-content>
    </mat-card>
    <pagination-controls (pageChange)="OnPaginateChange($event)" id="paginator"></pagination-controls>
  </div>
</div>

this showcases the CSS styles applied:

.verticalResultsBarContainerEnabled {

  background-color: #eeeeee;
  width: 16%;
  float: right;
  overflow: visible;

}

.verticalResultsBarContainerDisabled {
  display: none;
}

.card {

  margin-left: 10px;
  margin-right: 10px;
  margin-bottom: 10px;

}

.cardHighlight {

  margin-left: 10px;
  margin-right: 10px;
  margin-bottom: 10px;
  background-color: #c12400;
  color: white;
}

.innerDiv {
  height: 755px;
  overflow: auto;
}

.paginator {
  margin: auto;
  width: 92%;
}

provided below is a snippet of TypeScript code relevant to the issue:

highlightCard() {
    if (this.barStyle === 'card') {
      this.barStyle = 'cardHighlight';
    } else {
      this.barStyle = 'card';
    }
  }

I am facing an issue where clicking on a single mat card changes the color of the entire list instead of just the selected card. How can I correct this behavior?

Answer №1

Your cards need to have individual indexes for proper styling. This is a common issue. I noticed that you are using the same bar style for all your cards. Each card should have its own unique bar style when they are retrieved from the backend. To accomplish this, make changes in your .ts file:

service.subscribe(cards => {
let i = 0
cards.forEach(card => {
this.barStyle[i] = // set your default barStyle here;
i++;
});

If each car has an id, it's better to avoid using i. In your template:

<mat-card [ngClass]="barStyle[i]" *ngFor="let card of obs; let i = index | async | paginate: { id: 'paginator', itemsPerPage: 10, currentPage: currentPage, totalItems: totalItems }" (click)="highlightCard(i)">

You're using an async function in your template. So, in your ts file, you should expect an Observable. To update the style of each card, subscribe to your service and update the objects. Make the following changes:

cards: Observable should be changed to cards: Card[];

loadingData = true;

Call the service like this:

getData() {
this.loadingData = true;
service().subscribe(cards => {
cards.forEach(card => {
this.barStyle[card.id] = // set your default barStyle here;
this.cards = cards;
this.loadingData = false; // set to false after data is loaded
});
}

highlightCard(id: number) {
if (this.barStyle[id] === 'card') {
this.barStyle[id] = 'cardHighlight';
} else {
this.barStyle[id] = 'card';
}
}

In your template:

<mat-card ***ngIf="!loadingData"**
[ngClass]="barStyle[card.id]" 
*ngFor="let card of obs | async | 
paginate: { id: 'paginator',
itemsPerPage: 10,
currentPage: currentPage,
totalItems: totalItems }"
(click)="highlightCard(card.id)">

Sometimes, your template may render before the data is fully loaded, so use a boolean to wait for it.

**To maintain clean code, initialize variables for pagination in your .ts file*

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 arranging five images side-by-side in a row

I have a collection of 5 images: Image 1: Image 2: Image 3: Image 4: Image 5: The dimensions of each image are as follows: Image 1: 70x40 Image 2: 80x42 Image 3: 90x44 Image 4: 100x46 Image 5: 120x48 I would like to arrange these images ...

Troubleshooting NGINX and NodeJS (Docker) issue on Synology Server

I've set up a docker-compose file that does the following: Starts Postgres DB Builds and starts NestJS (NodeJS) backend on localhost:3000 Builds and starts an Angular app on localhost:4200 inside of an NGINX container After following these instructi ...

The hamburger menu for mobile devices is not functioning properly on the website's mobile version, however it operates correctly when the screen is resized

Currently, I am facing an issue with the hamburger menu not responding on my mobile device. Oddly enough, it does work when I resize my browser window to mimic a mobile size. There seems to be a glitch happening, but I'm struggling to pinpoint the exa ...

Lazy loaded modules do not have access to singleton services

After breaking my initial AppModule into multiple modules, I decided to lazy-load one of the modules while using singleton services from a shared module. Following the instructions provided in the official Angular documentation (link here) and in a tutori ...

Maintain dropdown menu visibility while navigating

I'm having an issue with my dropdown menu. It keeps sliding up when I try to navigate under the sub menu. I've spent all day trying to fix it, testing out various examples from the internet but so far, no luck. Any help would be greatly apprecia ...

What steps do I need to take to activate the legacy policy API for Google login?

The Legacy People API has not been utilized in project 145315848075 or it is currently disabled. To enable it, please go to and then attempt again. If you have recently activated this API, please wait a few minutes for the changes to take effect before ...

Leveraging the power of PHP includes with nested subdirectories

Hello, I recently configured my web server to run all .html files as .php files, allowing me to utilize the php include function, which has been very beneficial. However, I have various subdirectories with multiple files in each one. Homepage --banners ...

Incorporating CSS and JS files into a WordPress theme

To incorporate Css & Js files into my website pages, I plan to insert the following code into the functions.php file: function cssjsloading(){ wp_enqueue_style('bootstrap-rtl', get_template_directory_uri() . '/css/bootstrap-rtl.css&apo ...

What is the best way to pass a conditional true or false value to React boolean props using TypeScript?

I am currently utilizing the Material UI library in combination with React and Typescript. Whenever I attempt to pass a conditional boolean as the "button" prop of the component, I encounter a typescript error stating: Type 'boolean' is not assi ...

What is the best way to transform an array of objects into a nested array through shuffling

I am dealing with a diverse array of objects, each structured in a specific way: data = [ { content: { ..., depth: 1 }, subContent: [] }, { content: { ..., depth: 2 ...

Ensuring the CSS animation reaches its ultimate state by the end

I am currently implementing an animation on specific elements that have their opacity set to 0 in the CSS. The animation is triggered onClick, and via keyframes, it transitions the opacity from 0 to 1, among other things. However, once the animation compl ...

Angular Pipe -- Implicit type 'any' error occurs when trying to index type 'string' with an expression

Encountering an error while constructing the time ago pipe: Obtaining an implicit 'any' type due to inability to index type with a 'string' expression if (value) { const seconds = Math.floor( (+new Date() - +new Date(Numb ...

Do I really need all the dependencies suggested in the angular2 quickstart guide?

As a beginner in Angular 2, I have no prior experience with Angular 1. I recently came across this tutorial https://angular.io/guide/quickstart and I'm curious if all the suggested dependencies are truly essential. After running 'npm install&apo ...

Spinning an object using JQuery

I am currently working on a project to test my skills. I have set up a menu and now I want to customize it by rotating the icon consisting of three vertical lines by 90 degrees every time a user clicks on it. This icon is only visible on smartphones when t ...

Tips for automatically disabling cloudzoom based on image width

I'm currently utilizing cloudzoom with the given markup: <div id="container"> <img id="main-image" class="cloudzoom" src="/img/image1.jpg" data-cloudzoom="variableMagnification: false, zoomOffsetX: 0, zoomPosition: 'inside', zoom ...

"Import data from a text file and store it as an array of objects using Types

I need assistance with converting the information in my text file into an array of objects. Below is a snippet of the data from the text file: DOCNO NETAMOUNT IREF1 IREF2 DOCDT 001 30000 50 100 6/7/2020 2 40000 40 90 6/7/2020 Currently, t ...

Excessive white space within a relative block div causing the content to appear smaller in comparison

Currently, I am developing a straightforward form that includes CSS-based help boxes. These help boxes are designed to appear when the user hovers over the corresponding row. After leaving my project untouched for a few days, I encountered some bugs upon ...

Ways to recycle the table feature in angular2?

I am new to Angular2 framework and I am looking to efficiently reuse a single table component across my entire application. However, I am encountering challenges when it comes to displaying arrays in the table rows. How can I iterate through any type of ar ...

JavaScript - Delayed Text Appearance with Smooth Start

I want to create a landing page where the text appears with a slight delay - first, the first line should be displayed followed by the second line. Both lines should have an easing effect as they appear. Below is a screenshot of the section: https://i.sst ...

Show a few values as a string in Angular using Typescript

I am working with JSON data and I want to know how to display hobbies without including the word "all" in an Angular/TypeScript application. { "Name": "Mustermann1", "Vorname": "Max1", "maennlich& ...