Collapse a previously used item when a new item is opened within Angular

I've managed to create a tree structure for a sideBar Menu using this code, and it's working well. However, what I'm trying to achieve is that when a menu with submenus is expanded and the user clicks on another parent menu, the expanded submenu should collapse. Can anyone assist me with this?

 <ng-container *ngTemplateOutlet="treeViewList; context: { $implicit: pageMenus }"></ng-container>
  <ng-template #treeViewList let-list>
    <ul>
      <li *ngFor="let item of list">
        <a (click)="item.isopen = !item.isopen">
          <div>
            <mat-icon>{{ item.menuIcon }}</mat-icon>
            <span class="icon-text">{{ item.menuName }}</span>
          </div>
          <i class="fa fa-angle-right" [ngClass]="{ clicked: item.isopen }" aria-hidden="true"></i>
        </a>
        <ul *ngIf="item.children && item.isopen">
          <ng-container *ngTemplateOutlet="treeViewList;context: { $implicit: item.children }">
          </ng-container>
        </ul>
      </li>
    </ul>
  </ng-template

Here's the payload:

 pageMenus = [
    {
      "menuName": "Dashboard",
      "menuIcon": 'dashboard',
      "path": "",
      "children": [
        {
          "menuName": "Status",
          "menuIcon": "",
          "path": "/dashboard",
        }
      ]
    }, {
      "menuName": "Database",
      "menuIcon": 'layers',
      "path": "",
      "children": [
        {
          "menuName": "Users",
          "menuIcon": "",
          "path": "/user",
        },
        {
          "menuName": "Devices",
          "menuIcon": "",
          "path": "/device",
        },
        {
          "menuName": "Sessions",
          "menuIcon": "",
          "path": "/session",
        }
      ]
    }
]

https://i.sstatic.net/WxvsN.jpg

Answer №1

Consider using openIndex instead of isOpen variable for each item. Only display the child menu if itemIndex matches the open index.

 <ng-container *ngTemplateOutlet="treeViewList; context: { $implicit: pageMenus }"></ng-container>
  <ng-template #treeViewList let-list>
    <ul>
      <li *ngFor="let item of list; let index = index">
        <a (click)="openIndex = openIndex === index ? -1 : index">
          <div>
            <mat-icon>{{ item.menuIcon }}</mat-icon>
            <span class="icon-text">{{ item.menuName }}</span>
          </div>
          <i class="fa fa-angle-right" [ngClass]="{ clicked: openIndex === index }" aria-hidden="true"></i>
        </a>
        <ul *ngIf="item.children && openIndex === index">
          <ng-container *ngTemplateOutlet="treeViewList;context: { $implicit: item.children }">
          </ng-container>
        </ul>
      </li>
    </ul>
  </ng-template

Make sure to add a new variable called openIndex in your component.

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

Struggling with updating a user in MongoDB using findOneAndUpdate and encountering a frustrating internal server error 500?

Presently, I am in the process of developing an API that is designed to update the current user in mongoDB based on the data provided in the request. However, whenever I execute findOneAndUpdate(), I encounter a 500 internal server error. (I will outline ...

Unable to import global CSS in React; however, local components are working fine

My React application is having trouble loading global CSS styles. While local components are able to access their own styled-components, the global CSS styles are not being applied across all components. I have tried various import paths and different file ...

Angular-dc bar graph failing to display properly

I'm having some trouble creating a bar chart using crossfilter, dc.js, and angular-dc. The rowchart is working properly, but the barchart is not displaying the bars. When I inspect the element in Chrome, I can see the values, and when I force focus, t ...

Converting an Observable variable to a specific type in Typescript

I am currently utilizing Angular 12. To avoid duplicating the same service logic, I am experimenting with creating a base class that includes all HTTP methods and then extending a child class to utilize in the components. crud.service.ts @Injectable({ ...

Tips for dragging a column in ngx-datatable to scroll the horizontal scroll bar in Angular 4

Is there a way to make the horizontal scroll bar move when dragging the column header of ngx-datatable in Angular 4? I have a situation where the first column should trigger the movement of the horizontal scroll bar when dragged from left to right. Any s ...

What could be causing my tabs to shift to the vertical side when using large, larger, and wide screens?

In my previous research, I came across a question similar to mine: Pure CSS accordion not working within CSS tabs. The solution mentioned works perfectly on monitors of any size, but the difference lies in the use of the a element. In their code, setting t ...

The battle between Google Visualization API JSON and ArrayToDataTable in Python, a nightmare of data types

Initially, I developed a basic static google visualization page using python The python source code is as follows: def print_graph_script(temp_table): # google chart snippet chart_code=""" <script type="text/javascript" src="https://www.g ...

Building a table with the appendChild() method

I'm a beginner in the world of programming and I've been given a task to create a table of objects. I managed to do it using a certain method, but now I'd like to try creating it using the appendChild method. function addObject() { var ...

Separate each element with a time gap when using the .each() function in

Below is the code snippet that I have: $('.action-button').each(function(i, obj) { $(obj).trigger('click') }); I am looking to introduce a delay between each iteration of the loop, ideally a 5-second delay. Is it achievable through se ...

The make-xx-column() mixins in Bootstrap are malfunctioning

After careful examination, it looks like some of the Bootstrap mixins are not functioning as expected. Specifically, the .make-md-column() and .make-sm-column() seem to have no effect at all. Initially, I suspected that WebEssentials was not compiling the ...

Error message "$injector:unpr" occurs in the run method of AngularJS after minification process

I've encountered an issue with angular-xeditable on my Angular app. While it functions properly in the development environment, I'm facing an error in production when all JS files are minified: Uncaught Error: [$injector:strictdi] http://errors. ...

Body Zoom Browser

My website features buttons for zooming in and out, labeled as A + and A-. I wanted to make sure that the entire body of the website could be magnified easily. That's why I came up with this code: <html> <body> <style> .cont ...

What is the process for determining the estimated location of a queued event within a JavaScript Engine's event queue?

Imagine a multitude of events being created and added to the event queue of a Javascript engine. Are there any techniques or recommended practices in the industry to predict the order in which a specific event will be added to the queue? Any knowledge or ...

How is it possible for a local variable to be utilized outside of its original scope in code?

After obtaining a game demo from a website, I came across this particular code snippet: if(nx == food.x && ny == food.y) { var tail = {x: nx, y: ny}; score++; create_food(); } else { var tail = snake_array.pop(); tail.x = nx; ...

Securing Your Content - Preventing Users from Right-Clicking and Using F12 on Your Website

I am looking to disable the Right-Click function on my website or display an error message saying "Protected Content!" when someone tries to right-click. I want to prevent others from viewing my Source Code. Although I know how to disable Right-Click, I am ...

What steps can be taken to diagnose the cause of a failed Jquery AJAX request?

I am attempting to utilize the Yahoo Finance API to retrieve data in CSV format through Javascript. However, my current implementation shown below is not successful. $.ajax({ type: "GET", url: "http://finance.yahoo.com/d/quotes.csv?s=RHT+MSFT&f=sb2b3j ...

Tips for picking out a particular item from a list of child elements

When I select the first parent's children array, it ends up selecting every other parent's children as well. This is due to index 0 remaining the same for all of them. How can I specify and highlight a specific child? Link: Check out the stackb ...

Interrupting one process and initiating a new one

Trying to create a simple animation using Velocity.js. This animation will transition between two looping states upon clicking an svg. The first state involves horizontal scaling from scaleX(1) to scaleX(2.5) and back to scaleX(1), while maintaining scaleY ...

How can I solve export issues from index.ts after publishing to NPM?

I have a package called this package which contains an index.ts file. The corresponding index.d.ts file that is located in the directory node_modules/@fireflysemantics/slice has the following content: export { EStore } from './EStore'; export { ...

The website is not displaying CSS styles as intended

I'm currently in the process of building a website with Bootstrap 5, but I've encountered an issue where the properties from index.css are not taking effect on index.html. Specifically, when I hover over a service card, the background is supposed ...