'Angular - Create component tree menu
I am creating a tree menu, visually it looks like this:
The tree has been created based on an array of objects obtained from a service, extracted from a date property.
Now, I have to get the tree menu to allow displaying and collapsing the: years, months and complete dates, in the style of this component: https://angular2-tree.readme.io/
Ideally, I'd do this with typescript, but if it's hard for me, I'd try using an external component.
This is the html code:
<ul>
<li *ngFor="let y of tree | keyvalue">{{y.key}}
<ul>
<li *ngFor="let m of tree[y.key] | keyvalue">{{m.key}}
<ul>
<li *ngFor="let d of tree[y.key][m.key] | keyvalue">{{d.key}}
<ul>
<li *ngFor="let h of tree[y.key][m.key][d.key]"><a [ngClass]="{'hourSelected': (idSchedule === h.id || lastId === h.id),'hourUnSelected': idSchedule !== h.id}" (click)="loadMacroProcesses(h.id)">{{h.hour}}</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
This would be the solution, now I will refine it:
<ul>
<li id="year" *ngFor="let y of tree | keyvalue; let i=index" (click)="listClick($event, i)">{{y.key}}
<ul [hidden]="indexExpandedYear!=i?true:null">
<li id="month" *ngFor="let m of tree[y.key] | keyvalue; let j=index" (click)="listClick($event, j)">{{m.key}}
<ul [hidden]="indexExpandedMonth!=j?true:null">
<li id="day" *ngFor="let d of tree[y.key][m.key] | keyvalue; let k=index" (click)="listClick($event, k)">{{d.key}}
<ul [hidden]="indexExpandedDay!=k?true:null">
<li *ngFor="let h of tree[y.key][m.key][d.key]"><a [ngClass]="{'hourSelected': (idSchedule === h.id || lastId === h.id),'hourUnSelected': idSchedule !== h.id && lastId !== h.id}" (click)="loadMacroProcesses(h.id)">{{h.hour}}</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
This is the typescript method:
listClick(event, i) {
switch (event.srcElement.id) {
case "year":
this.indexExpandedYear = this.indexExpandedYear==i?-1:i;
event.stopPropagation();
break;
case "month":
this.indexExpandedMonth = this.indexExpandedMonth==i?-1:i;
event.stopPropagation();
break;
case "day":
this.indexExpandedDay = this.indexExpandedDay==i?-1:i;
event.stopPropagation();
break;
default:
break;
}
}
Can you recommend me a good one external component? Thanks.
NOTE: I am working with version 11 of Angular
NOTE: If you deploy one year, the rest of the years should be collpased back.
NOTE: Angular material is not valid for me
Solution 1:[1]
You could add a parameter for visibility and click event to the parent ul. How it would work is that they would have a boolean value on them for visibility that would change when you click the top ul element. You would have a method that would just switch between true/false and display if true hidden if false. Click event should be on the top li element and visibility on its child.
Solution 2:[2]
You should checkout the tree component provided by primeng. It has its own data format and can do your own customisation on top it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Macik |
| Solution 2 | Jibin Philipose |

