1

I have found similar scenarios to this one, but I haven't yet found this exact scenario. Sorry if I missed it.

In Angular 8, I am using an *ngFor to iterate through some message objects. This displays the message title and date/time in a row of vertical boxes to the left of the screen. What I'm trying to get to is when one box is clicked, it becomes active and changes color. I have this working, but the problem is that the "active" class does not inactivate when another box is clicked. This is the problem I'm trying to solve.

Here is my current code with CSS:

<div *ngFor="let msg of messages; let i = index">
  <a class="list-group-item list-group-item-action" 
      data-toggle="list" href="#home" role="tab" 
      [ngClass]="{ 'active' : isActive}" (click)="popIt(i)">
    <span id="msgSubject1">{{msg.Subject}}</span>
    <br />
    <span class="datetimeCls" id="datetime1">
      {{msg.DateCreated | date : 'short' }}
    </span>
  </a>
</div>
popIt(num: string) {
  var number = num;
  this.SubjectDisplay = this.messages[num].Subject;
  this.DateDisplay = this.messages[num].DateCreated;
  this.TextDisplay = this.messages[num].Body;
}
.list-group .list-group-item {
  color: grey;
  font-weight: bold;
  font-family:"Gill Sans" Verdana;
  font-size: 15px;
  background-color: #FFFFFF;
}

.list-group .list-group-item.active {
  background-color: lightgray !important;
  border-top: solid 2px grey;
  border-bottom: solid 2px grey;
  color: grey;
}

This displays the object properties as expected, the clicks work, but it makes every box active as they're clicked. They do not inactivate.

Any direction, suggestions or examples would be appreciated! Thank you!

3
  • Can you show the relevant code from the component - that's crucial to understanding the problem here. Commented Mar 23, 2020 at 19:13
  • 2
    isActive seems to be a common variable, you need to have something like msg.isActive and toggle the same in popIt() Pass msg directly: popIt(msg) Commented Mar 23, 2020 at 19:14
  • @KurtHamilton I added the popIt() method, sorry about missing that. Commented Mar 23, 2020 at 19:18

2 Answers 2

1

One way to do it is to have an activeMessage property:

public activeMessage: Message; // Use the appropriate type here

which is set on click and tested in the class binding:

<div *ngFor="let msg of messages">
  <a [class.active]="msg === activeMessage"
    (click)="activeMessage = msg; doOtherStuff()" ... >
    ...
  </a>
</div>

See this stackblitz for a demo.

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

Comments

0

Change your code and store information in your parent component about some unique identifier of message which was clicked. And then you can easily add click listener to component and inside of parent component update stored id. But you have to change a little you HTML [ngClass] directive, to return true if message.Id===clickedMessageId. Or you can store whole message in f.e. clickedMessage, then you can do message===clickedMessage. Another way you can achieve it, you can create custom directive and service, when you click directive notify service to unclick every other object. But you have to remember to remove them from service, once directive has been destroyed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.