Reputation: 393
I am currently working on a project where I display a list of complaints in a zippy/accordion. I receive an array of key-value pairs as my dataset in my component.ts file, given below as:
isExpanded: boolean;
complaints: any[] = [
{"CALLER”:"1234567890", "DURATION”:"45", "CALLTIME":"2020-06-14T02:12:00.000Z", "COMPLAINTTITLE":"Device Not Working", "COMPLAINTMESSAGE":"My device has some issue"},
{"CALLER":"1357924680", "DURATION":"83", "CALLTIME":"2020-06-14T06:23:58.000Z", "COMPLAINTTITLE":"Device Not Working", "COMPLAINTMESSAGE":"My device has some issue"},
{"CALLER":"2468013579", "DURATION":"123", "CALLTIME":"2020-06-14T10:44:20.000Z", "COMPLAINTTITLE":"Device Not Working", "COMPLAINTMESSAGE":"My device has some issue"},
{"CALLER":"0864297531", "DURATION":"94", "CALLTIME":"2020-06-14T15:21:04.000Z", "COMPLAINTTITLE":"Device Not Working", "COMPLAINTMESSAGE":"My device has some issue”},
{"CALLER”:"9753108642", "DURATION":"126", "CALLTIME":"2020-06-14T20:18:50.000Z", "COMPLAINTTITLE":"Device Not Working", "COMPLAINTMESSAGE":"My device has some issue”}
];
toggle(){
this.isExpanded = !this.isExpanded;
}
In my component.html file, I have used an ngFor directive to populate the zippy.
<div class="zippy" *ngFor="let complaint of complaints”>
<div class="zippy-heading" [class.expanded]="isExpanded" (click)="toggle()">
<p>
Caller: {{ complaint.CALLER }}<br>
Time: {{ complaint.CALLTIME }}<br>
Duration: {{ complaint.DURATION }} sec<br>
Title: {{ complaint.COMPLAINTTITLE}}
</p>
</div>
<div *ngIf="isExpanded" class="zippy-body">
<p>Message: {{ complaint.COMPLAINTMESSAGE }}</p>
</div>
</div>
I have noticed that when I click on any title div, all of the messages are displayed. How do I get to open only the selected one that I had clicked?
Upvotes: 0
Views: 343
Reputation: 38847
At minimum you could move div.zippy
and it's children to a new component where each has it's own isExpanded
. That way when one is expanded, it does not effect others:
Parent (loop over complaints
and pass complaint
as input):
<div class="whatever">
<app-foo *ngFor="let complaint of complaints" [complaint]="complaint"></app-foo>
</div>
Child Template:
<div class="zippy">
<div class="zippy-heading" [class.expanded]="isExpanded" (click)="toggle()">
<p>
Caller: {{ complaint.CALLER }}<br>
Time: {{ complaint.CALLTIME }}<br>
Duration: {{ complaint.DURATION }} sec<br>
Title: {{ complaint.COMPLAINTTITLE}}
</p>
</div>
<div *ngIf="isExpanded" class="zippy-body">
<p>Message: {{ complaint.COMPLAINTMESSAGE }}</p>
</div>
</div>
Child Component:
import { Component, OnInit, Input } from "@angular/core";
@Component({
selector: "app-foo",
templateUrl: "./foo.component.html",
styleUrls: ["./foo.component.css"]
})
export class FooComponent {
@Input() complaint: any; // ideally use strict typing instead
isExpanded: boolean = false;
toggle() {
this.isExpanded = !this.isExpanded;
}
}
Here is an example in action.
The next steps would be to use a strategy from component interaction to perhaps close other elements/complaints when another is toggled. Keep in mind you can also add a open/close state value to the complaints
to track/manipulate that state.
Hopefully that helps!
Upvotes: 1