Angular 8 allows for the utilization of Ul li elements to create an expandable and collapsible hierarchical

As a newcomer to Angular, I have managed to code a representation of hierarchical JSON data in a tree view using recursive calls. The code works well, but I am faced with the challenge of implementing an expand and collapse functionality for the treeView using a CARET icon.

<h1>Angular 2 Recursive List</h1>
<ul>
  <ng-template #recursiveList let-list>
    <li *ngFor="let item of list">
      {{item.name}}
      <ul *ngIf="item.children.length > 0">  
        <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.children }"></ng-container>
      </ul>
    </li>
  </ng-template>
  <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: menuList}"></ng-container>
</ul>

The content of "menuList"

[
  {
    "menuId": 1,
    "menuName": "Inspection",
    "icon": "",
    "type": 1,
    "formId": 0,
    "formUUID": null,
    "formName": null,
    "menu": [
      {
        "menuId": 17,
        "menuName": null,
        "icon": "",
        "type": 2,
        "formId": 0,
        "formUUID": "2f84a801-cc3e-4807-a68c-cdd3cc9df9af",
        "formName": "Production Line",
        "menu": null
      }
    ]
  }
]

Answer №1

<h1>A Recursion Example in Angular 2</h1>
<ul>
  <ng-template #recursiveExample let-list>
    <li *ngFor="let item of list">
      {{item.name}}
      <!--add a button-->
      <button (click)="item.isopen=!item.isopen">Toggle</button>
      <!--change the condition-->
      <ul *ngIf="item.children.length > 0 && item.isopen">  
        <ng-container *ngTemplateOutlet="recursiveExample; context:{ $implicit: item.children }"></ng-container>
      </ul>
    </li>
  </ng-template>
  <ng-container *ngTemplateOutlet="recursiveExample; context:{ $implicit: someList}"></ng-container>
</ul>

<!--just for debugging values-->
<pre>{{someList|json}}</pre>

Answer №2

After finding the solution, everything is now working as expected. It's also possible to perform CRUD operations with these lists.

<ng-container *ngTemplateOutlet="treeViewList;context:{$implicit:menuListCopy}"></ng-container>
        <ng-template #treeViewList let-list>
            <ul>
                <li *ngFor="let item of list;" style="color: black;">
                    <i class="fa" *ngIf="item.menu" [ngClass]="item.isopen ? 'fa fa-caret-down': 'fa fa-caret-right'"
                        (click)="item.isopen=!item.isopen" style="font-size: larger;">
                    </i>
                    <span *ngIf="item.type == 1"
                        id="menuName" matTooltip="Edit Menu">
                        <span (click)="menuTrigerred(item)">{{item.menuName}}</span>
                        <button matTooltip="Create subMenu" (click)="addChildMenu(item)" class="iconBtn" style="font-size: 13px;">
                            <i class="fa fa-plus"></i>
                        </button>
                        <button matTooltip="Delete Menu" class="iconBtn" (click)="deleteMenu(item)" style="font-size: 11px;">
                            <i class="fa fa-trash" aria-hidden="true"></i>
                        </button>
                    </span>
                    <span *ngIf="item.type == 2" matTooltip="Forms">
                        {{item.formName}}
                    </span>
                    <ul *ngIf="item.menu && item.isopen">
                        <ng-container *ngTemplateOutlet="treeViewList;context:{$implicit:item.menu}"></ng-container>
                    </ul>
                </li>
            </ul>
        </ng-template>

https://i.stack.imgur.com/gjPLn.jpg

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue: The element p-button (and p-password) is unrecognized

After installing primeng using the command npm install primeng --save, I have version ^12.0.1 of primeng listed in both dependencies and devDependencies in my package.json file. In my angular.json file, I have included the necessary styles: "styles& ...

Explore the Attribute and generate a Text-Node using the Renderer

Given the advice against directly accessing the DOM in Angular for various platforms, I am trying to figure out how to achieve the following using Renderer: a) Store the offsetLeft value of $event.target in a variable called left. b) Create a text node wi ...

Angular 6's Select feature is failing to properly update user information

We are currently facing an issue with our user profile edit form. When users try to update their information by changing simple input fields, the changes are reflected successfully. However, when they make selections in dropdown menus, the values do not ge ...

Switching slides in Ionic 4 with a simple button click

I want to switch slides by clicking a button on my presentation. Here is an example code snippet: <ion-slides> <ion-slide> Slide one <ion-slide> <ion-slide> Slide Two <ion-slide> </ion-slides> <butt ...

Can errors be selectively ignored in Angular's global error handler based on certain conditions?

I am currently facing a situation where I need to handle errors when calling an API to save data, either manually or automatically. For manual saves, I have implemented an Angular global error handler to display the error message if the save fails. Howeve ...

I desire to obtain an image from a different webpage

I am a beginner in the world of Ionic/Angular. On my edit profile page (which is a separate page), I have the ability to change my profile picture. When I make this change, it should automatically reflect on my main profile page, which is on another page. ...

Encountering Angular Material UI issues following the transition from version 11 to 12

I am currently in the process of updating my Angular application from version 11 to 12, integrating Angular Material, and encountering some error messages: Error No.1 - Error NG8002: Cannot bind to 'ngModel' as it is not a recognized property of ...

Apply a CSS class once a TypeScript function evaluates to true

Is it possible to automatically apply a specific CSS class to my Div based on the return value of a function? <div class="{{doubleClick === true ? 'cell-select' : 'cell-deselect'}}"></div> The doubleClick function will ret ...

Leverage the capabilities of mat-datepicker independently without relying on an

Is it possible to have the datepicker located in a fixed sidebar that is always visible and not linked to an input field? My idea was to include the component and set opened = true so that the datepicker remains in a box that is constantly displayed. ...

Is there a hashing algorithm that produces identical results in both Dart and TypeScript?

I am looking to create a unique identifier for my chat application. (Chat between my Flutter app and Angular web) Below is the code snippet written in Dart... String peerId = widget.peerid; //string ID value String currentUserId = widget.currentId ...

Different ways to reference a variable in Typescript without relying on the keyword "this" throughout the codebase

Can we eliminate the need to write "this" repeatedly, and find a way to write heroes, myHero, lastone without using "this"? Similar to how it is done in common JavaScript. https://i.stack.imgur.com/TZ4sM.png ...

What are the benefits of reverting back to an Angular 1 directive instead of using an Angular 2 application

Our team has created numerous Angular 1 components and is eager to incorporate them into our Angular 2 application. However, the documentation suggests that we must downgrade the Angular 2 application in order to integrate and utilize the Angular 1 direc ...

Struggling to dynamically update array values by comparing two arrays

I am faced with a scenario where I have two arrays within an Angular framework. One of the arrays is a regular array named A, containing values such as ['Stock_Number', 'Model', 'Type', 'Bill_Number'] The other arr ...

Troubleshooting: Data retrieval issues in AngularFire within Ionic and Angular Application

I am encountering errors and facing issues with data retrieval in my Angular and Ionic application when using AngularFire for Firebase integration. Here is a snippet from my package.json file: "dependencies": { "@angular/common": "5.0.3", "@angul ...

Two lines in ChartJS with distinct fill gradients for each

I am facing an issue with ChartJS version 2.6 in my Ionic 3/Angular 4 app. I have set up a line chart config with 2 datasets, but I am struggling to apply individual fill gradients to each line. What I am aiming for is something like this: https://i.stac ...

Encountering [Object Object] within an angular2 app

https://i.stack.imgur.com/iceKH.pngI recently created an angular2 application using ngrx/effects for handling http calls. My reference point was an application on GitHub. However, I am facing an issue where the response from the HTTP call is not displaying ...

Error encountered while injecting Angular dependencies in component constructor

Here is my newly created component. I am looking to allow users to adjust the count variable. import { Component, Inject } from '@angular/core'; @Component({ selector: 'app-likebtn', templateUrl: './likebtn.component.html&apos ...

Adding a tooltip to an Angular Material stepper step is a great way to provide

I am trying to implement tooltips on hover for each step in a stepper component. However, I have encountered an issue where the matTooltip directive does not seem to work with the mat-step element. <mat-horizontal-stepper #stepper> <mat-step lab ...

What is the proper way to validate a property name against its corresponding value?

Here is the structure of my User class: export class User { public id: number; //Basic information public email: string; public firstName: string; public lastName: string; //Permissions public canHangSocks: boolean; p ...

How can I display JSON values without revealing the parent in Angular 5 and Ionic 3?

I am trying to extract values from JSON without the parent keys. Here is the JSON structure I have: [ { "companies": [{ "id": 1, "name": "Prueba", "company_number": "23423423A", "latitude": 241241.12, "lo ...