1

So though my question might sound familiar the case is a bit different. I have a screen with multiple tasks. To show the tasks I am iterating via the data and my code looks something like

  

  <div *ngFor="let task of tasks" class="scheduleContainer inline-block shadow">
      <div id="myHeader" #myHeader class="activeHeader">
        {{task.title}}
      </div>
      <div class="detailsBox">
        <div class="row">
          <div class="offset-md-1 col-md-auto">
            Last Date:
          </div>
          <div class="col-md-auto">
            {{task.lastDate}}
          </div>
        </div>
        <div class="row">
          <div class="offset-md-1 col-md-auto">
            Duration:
          </div>
          <div class="col-md-auto">
            {{task.duration}}
          </div>
        </div>
        <div class="row">
          <div class="offset-md-1 col-md-auto">
            Total Runs:
          </div>
          <div class="col-md-auto">
            {{task.totalRun}}
          </div>
        </div>
      </div>
      <div class="footer">
        <a [routerLink]="['edit-scheduled-tasks']">edit schedule</a> &nbsp;
        <a [routerLink]="['view-history-scheduled-tasks']">view history</a> &nbsp;
        <a (click)="onClick()">enable task</a> &nbsp;
        <a href="" *ngIf="flag==task.isRunNow">run now</a>
      </div>
    </div>

    <router-outlet></router-outlet>

Now when I click on the enabled task, I would like the color of that particular div to be changed. In my component, I tried something like

   onClick() {
        this.myHeader.nativeElement.style.background = 'red';
      }

So this did change the color but it did not change the current task but rather some other task. Suggestions?

4
  • I guess it changed the task.title? Commented Oct 2, 2018 at 15:02
  • @tomerraitz not sure what you mean.. But the div with the id as myHeader needs to change color for that particular task clicked. Commented Oct 2, 2018 at 15:04
  • This will always change the color of the last task, probably because you have the same reference myHeader for each task. Commented Oct 2, 2018 at 15:06
  • try maybe (click)="onClick(this)" and onClick(el) { el.myHeader.style.background = 'red'; } Commented Oct 2, 2018 at 15:13

3 Answers 3

2

you can access myHeader from template so you can change the color something like this

  <div id="myHeader" #myHeader class="activeHeader">
        Change the color by myHeader variable
  </div>

  <button (click)="myHeader.style.background='red'">click</button>

or you can use a property with ngStyle like this

<div [ngStyle]="{'background-color':color}" >
          Another way by ngStyle
 </div>

 <button (click)="color='red'">click</button>

or you can use a property to toggle class with ngClass

<div [ngClass]="{'red':isClicked}" >
  Set class 
</div>

<button (click)="isClicked=!isClicked">Toggle class</button>

Example toggle color of taskList by useing ngClass

template

<div *ngFor="let task of taskList" 
    [ngClass]="{'red':selectedTasks[task.id]}" 
    (click)="selectedTasks[task.id]= !selectedTasks[task.id]" class="task">
   {{task.name}}
</div>

or you can use button to toggle the state

<div *ngFor="let task of taskList" 
    [ngClass]="{'red':selectedTasks[task.id]}" 
     class="task">
   {{task.name}} 
   <button (click)="selectedTasks[task.id]= !selectedTasks[task.id]">toggle {{task.name}}</button>
</div>

if you want to set the state without toggle on click event just set the state to true like this selectedTasks[task.id] =true

component

  taskList =[
    {id:1 , name:'Task 01'},
    {id:2 , name:'Task 02'},
    {id:3 , name:'Task 03'},
    {id:4 , name:'Task 04'},
    {id:5 , name:'Task 05'},
  ];

  selectedTasks = {};

stackblitz demo

Sign up to request clarification or add additional context in comments.

5 Comments

Well yes, I mean I am able to change the color but since I have multiple tasks and I click on that particular one then it should only for that particular task, not something else and with my code it is changing the color of the header but for some other task.
You need to create something like flag as an example base on task id and use it to toggle class to change the color ngClass will work fine , did you got my point ?
I see where you are going, let me go ahead and do that, thanks!
I have update my answer and the demo you can check the task list example @bshah
I ended up using "Example toggle color of taskList by using ngClass" with little modification, was wondering if it is possible to change the text as well for the button from where you would click
0

Not a clean way to do, but it still works. Send an index of selected element to onClick(i) and add the color to selected div. So that you don't mess with template reference.

html

<div *ngFor="let task of tasks; let i=index;" class="scheduleContainer inline-block shadow">
    <div id="myHeader" #myHeader class="activeHeader">
        {{task}}
    </div>
    <div class="footer">
        <a (click)="onClick(i)">enable task</a> &nbsp;
    </div>
</div>

component.ts

 onClick(index: number) {
     document.querySelectorAll('#myHeader')[index]
      .style.background = 'red';
  }

DEMO

Comments

0

It's not a good practice to manipulate DOM directly.
Angular: Stop manipulating DOM with ElementRef!

As an alternate, It's easy to bind inline style in your Angular templates using style binding.

Since you would like the color of that particular div to be changed. Use A boolean array:

component:

 export class AppComponent  {
  name = 'Angular';
  public styleArray=new Array<boolean>(10);

  onClick(i)
  {
    this.styleArray[i]=true;
  }
}

While Iterating pass index to onClick(i) to set particular index of array true and apply style dynamically

[style.color]="styleArray[i] ? 'green':'black'"  


  <div *ngFor="let task of tasks; let i=index" class="scheduleContainer inline-block shadow">
          <div id="myHeader" [style.color]="styleArray[i] ? 'green':'black'"  class="activeHeader">
            {{task.title}}
          </div>
........rest of the code
 <a (click)="onClick(i)">enable task</a> &nbsp;

Live Demo

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.