poporp
poporp

Reputation: 71

Select Menu Open/Close

In the sidebar, I have two rubrics Category and Markets.

enter image description here

When I click on Category, the items display correctly.

enter image description here

My problem is that if I click on another rubric, for example, if I click on Markets. The Category rubric does not close automatically.

enter image description here

I tried to call showSubmenu method but without success. Here is a reproduction on Stackblitz, and here is code:

HTML

<div class="sidebar" [class.sidebar-close]="!openSidebar" >
    <div class="logo-details">
        <img src="https://zupimages.net/up/22/42/refj.png" /> 
    </div>
    <ul class="nav-links" id="nav-links" >
      <li *ngFor="let item of menuSidebar" #itemEl >
        <div *ngIf="item.sub_menu.length > 0" class="dropdown-title" (click)="showSubmenu(itemEl)">
          <a (click)="selectMenu(item)">
            <i [class]="item.icon"></i>
            <span class="link_name">{{item.link_name}}</span>
          </a>
          <i class='bx bxs-chevron-down arrow'></i>
        </div>
        <ul class="sub-menu" [class.blank]="item.sub_menu.length == 0">
          <li><a class="link_name">{{item.link_name}}</a></li>
          <li *ngFor="let item_sub of item.sub_menu" routerLinkActive="active">
            <a [routerLink]="[item_sub.link]">{{item_sub.link_name}}</a>
          </li>
        </ul>
      </li>
    </ul>
  </div>

dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { MenuSidebar } from './types/menuSidebar';


@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

    openSidebar: boolean = true;

    menuSidebar: MenuSidebar[] = [
       {
        link_name: 'Category',
        link: null,
        icon: 'bx bx-collection',
        active: false,
        sub_menu: [
          {
            link_name: 'Portfolio',
            link: '/category/portfolio',
          }, 
          {
            link_name: 'Contact',
            link: '/category/contact',
          }, 
        ]
      },
      {
        link_name: 'Markets',
        link: null,
        icon: 'bx bx-collection',
        active: false,
        sub_menu: [
          {
            link_name: 'Indice',
            link: '/markets/indice',
          }, 
        ]
      },
    ]
  
    constructor() { }
    ngOnInit() {}
  
    showSubmenu(itemEl: HTMLElement) {
      itemEl.classList.toggle('showMenu');
    }

    selectMenu(parentMenu: { link_name: string }) : void {

      this.menuSidebar.forEach(menu => {
        if (menu.link_name !== parentMenu.link_name) {
          menu.active = false;
        } else {
          menu.active = !menu.active;
        }
      });
    }
  }

Upvotes: 0

Views: 385

Answers (1)

Mehyar Sawas
Mehyar Sawas

Reputation: 1266

If you always have one expanded menu item, then it is easier to use a variable to store the active item and bind the expand class to that variable like this:

activeItem;

  toggleShowSubmenu(item: any) {
    if (item.link_name == this.activeItem) {
      this.activeItem = undefined;
    } else {
      this.activeItem = item.link_name;
    }
  }

In your template

<li *ngFor="let item of menuSidebar" [class.showMenu]="activeItem == item.link_name" #itemEl>

And then you pass the item object instead of the html element reference

(click)="toggleShowSubmenu(item)"

Here is a fork of your example with my suggested solution

Upvotes: 2

Related Questions