angular: set different color to paragraphs with ngFor
Asked Answered
C

4

5

When I click on a button, I am adding strings to an array and I need to show these strings in a page. But I need to show the text red only after 5th element (first 5 elements should have the text black). Here is what I've tried:

the component code:

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

@Component({
  selector : 'app-toggle',
  templateUrl : './toggle.component.html',
  styleUrls : ['./toggle.component.css']
})
export class ToggleComponent {
  toggleState = false;
  clickNumber = 0;
  actions = [];
  action = 'Display';

  onClick() {
    this.clickNumber++;
    this.toggleState = !this.toggleState;

    if (this.toggleState) {
      this.action = 'Display';
    } else {
      this.action = 'Hide';
    }
    this.actions.push('click number: ' + this.clickNumber.toString() + ', changed the state to ' + this.action);
  }

  getColor(): string {
    if (this.clickNumber > 5) {
      return 'red';
    } else {
      return 'black';
    }
  }
}

and the html code:

<button (click)="onClick()" >{{action}} details</button>
<p *ngIf="toggleState">Password details: secret</p>
<p *ngFor="let act of actions" [ngStyle]="{'color' : getColor()}">{{act}}</p>

but my problem is that after I click more that 5 times, all the paragraph elements change the text color. So how to achieve this? What I've done wrong? I am using angular 6.

Here is how my page looks:

enter image description here

Chiang answered 8/7, 2018 at 17:45 Comment(0)
E
5

You can use the index property of *ngFor, along with ngStyle like so:

<p *ngFor="let act of actions; let i = index" [ngStyle]="{'color' : i > 5 ? 'red' : 'black'}">{{act}}</p>
Eventuate answered 8/7, 2018 at 17:48 Comment(5)
i do not think the = is needed! anyway you're the fastestKalong
Because they're all using the same property, i.e. clickNumber. If it's > 5 for one, it must be > 5 for them allEventuate
so when a new item is added, the whole html is recreated? because I've tought that only the new element is added and the rest are there from the previous clicksChiang
When the changeDetection is run, it will call getColor() again for each elementEventuate
@BudaGavril , when the clickNumber is 6, all the elements call that function with value 6. So they all get red. But if you pass the current element's value while calling, you will get the desired output. You can also check my answer for further clarification :) But this is a standard solution by user184994Pinchhit
K
3

Use the ngStyle with the condition >5

<p *ngFor="let act of actions; let i = index" [ngStyle]="{'color' : i > 5 ? 'red' : 'black'}">{{act}}</p>
Kalong answered 8/7, 2018 at 17:49 Comment(0)
C
1

If I may suggest a much easier css solution, using nth-child

p:nth-child(n+6) {
  color: red;
}
<p>
Foo
</p>
<p>
Foo
</p>
<p>
Foo
</p>
<p>
Foo
</p>
<p>
Foo
</p>
<p>
Foo
</p>
<p>
Foo
</p>
<p>
Foo
</p>
Conqueror answered 8/7, 2018 at 17:51 Comment(1)
Serial downvoter, you’re ok? Amazing how fast you’re clicking. :DConqueror
P
1

Fix - 1 : Modify getColor() function

Pass the current index value, otherwise the clicknumber will be same for all the elements when it is 6

 getColor(current): string {
    if (current > 5) {
      return 'red';
    } else {
      return 'black';
    }
  }

HTML

<button (click)="onClick()" >{{action}} details</button>
<p *ngIf="toggleState">Password details: secret</p>
<p *ngFor="let act of actions;let i = index" [ngStyle]="{'color' : getColor(i)}">{{act}}</p>

Working example : stackblitz

Pinchhit answered 8/7, 2018 at 18:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.