Angular Navigation Drop-down Menu

In my quest to develop an intricate breadcrumbs system paired with dropdown navigation, I've encountered a challenge:

https://i.sstatic.net/RZUDr.png

The issue revolves around handling outside clicks: specifically, closing dropdowns when clicking outside the element. However, if another navigation item is clicked, it should remain open as only one breadcrumb is active at a time.

My approach involves:

1) Detecting outside clicks by containing an event target within the parent element

2) Switching occurs by closing all breadcrumbs and opening the required one.

View a simple example of the breadcrumbs on Plunker here

Template:

<ul #simpleBreadcrumbs>

  <li *ngFor="let breadcrumb of breadcrumbs"
    class="bread_item"
    (click)="toggleStateOfSubparagraphs(breadcrumb)">

    <div>
      <span>{{breadcrumb.label}}</span>
      <i class="icon-arrows-glyph-1_bold-down"
         *ngIf="!breadcrumb.isOpen"></i>
      <i class="icon-arrows-glyph-1_bold-up"
         *ngIf="breadcrumb.isOpen"></i>
    </div>

    <ul class="switcher__list dropdown__list"
        *ngIf="breadcrumb.isOpen">
      <li class="switcher__item dropdown__item" *ngFor="let subparagraph of breadcrumb.subparagraphs">
        <a class="switcher__item-href">{{subparagraph.label}}</a>
      </li>
    </ul>

  </li>
  
</ul>

Component Class:

export class App {
  breadcrumbs:any[];

  @ViewChild('simpleBreadcrumbs') private _breadcrumbsTemplate: ElementRef;
  _currentOpenedBreadcrumb:any;

  constructor() {
    this.breadcrumbs = [
      {
        label: 'First',
        isOpen: false,
        subparagraphs: [
          {label: '1.1'},
          {label: '1.2'}
        ]
      },
      {
        label: 'Second',
        isOpen: false,
        subparagraphs: [
          {label: '2.1'},
          {label: '2.2'}
        ]
      }
    ];
  }

  toggleStateOfSubparagraphs(breadcrumb) {
    if (this._currentOpenedBreadcrumb === breadcrumb) {
      this._closeSubparagraphs();
      this._currentOpenedBreadcrumb = null;
      return;
    }
    
    this.breadcrumbs.forEach((bread: IBreadcrumb) => {
      bread.isOpen = false;
      if (bread === breadcrumb) {
        bread.isOpen = true;
      }
    });
    
    this._currentOpenedBreadcrumb = breadcrumb;
  }

  _closeSubparagraphs() {
    this.breadcrumbs.map((bread) => {
      bread.isOpen = false;
      return bread;
    });
  }

  @HostListener('window:keydown', ['$event'])
  public onEscapeClick(event: KeyboardEvent): void {
    if (event.which === 27 && !this._breadcrumbsTemplate.nativeElement.contains(event.target as Node)) {
      this._closeSubparagraphs();
    }
  }

  @HostListener('document:click', ['$event'])
  public onOutsideClick(event: Event): void {
    if (!this._breadcrumbsTemplate.nativeElement.contains(event.target as Node)) {
      this._closeSubparagraphs();
    }
  }
}

Answer №1

Here is the updated CSS code:

.bread_item {
 list-style: none;
 float: left;
 padding: 30px;

}

Does this meet your requirements? If not, I may have misunderstood your request.

Your initial CSS caused the second element to be affected when clicking the first element.

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

Creating links in CodeIgniter with the 'anchor' function

I recently started working with the codeigniter framework and I need help converting this PHP code into a Codeigniter version echo '<td><a rel="facebox" href=useredit.php?emp_id='. $row['emp_id'] .'><button type="bu ...

Ways to permanently change a javascript array object

I am facing an issue with my object array in the store file of my app, which I'm using MobX for. Whenever I try to modify or add to an object in the array, the data gets deleted upon refreshing the page. Is there a way to make these changes to the obj ...

Try enabling automatic status bar filling in Onsen UI when working with AngularJS

Completely new to AngularJS, I am trying to understand how to use ons.enableAutoStatusBarFill(); in order to prevent my menus from overlapping the status bar. This is how I have set up my controller: var mod = ons.bootstrap('app', ['onsen& ...

Encountering an ENOENT error while attempting to incorporate a style guide into next.js (react)

Recently, I delved into learning next.js and decided to enhance my project with documentation using To kickstart my project, I utilized npx create-next-app After installation and configuration setup, I added the following code snippet: [styleguide.config ...

Express-openapi routes are giving a 404 error

As a beginner in the world of openapi, I have been attempting to transition an existing express application to work with openapi. After diligently following the provided documentation, I decided to convert one of my routes to openapi to test it out (disab ...

Guide on parsing JSON data received from the frontend

Here is the HTML code that I am working with: <div id="loginform"> <form class="loginIn" name="loginform"> <input type="text" name="login"> <input type="password" name="password"> <input type="submit" value="Войт ...

Error: The src for the image of the double cheeseburger could not be properly parsed by the `next/image` component

Could you kindly take a moment to review this? import Image from "next/image"; import { useState, useEffect } from "react"; import "@/data/data.json"; interface propsData { dish: { id: numbe ...

Certain items in Angular may lack a value for a specific property

I'm currently working on an Angular2 app and I have a dilemma regarding how to structure my main class. For this project, I will need to create a total of 78 instances of a class. The issue is that not all 78 instances share the exact same properties ...

Including an anchor element with a specified URL, alongside passing the URL as a property

Having trouble passing a URL to href using a property. I'm attempting to pass the {props.github} value to href, but it's not working as expected. I've set up a property object with a field called github like this: export const projectList ...

Ember application experiencing trouble displaying Facebook Like Box

I’m currently facing an issue with integrating the like box into our ember app, specifically in a template named about. The problem arises when users enter the ember app from a different route, instead of directly accessing the about route. In such cases ...

Include image hover text without using HTML

I am looking to add a hover effect to some images using CSS and JS since I cannot directly edit the HTML file. The goal is to have centered text pop out when hovering over certain images. I know the div class of the image but unfortunately, I cannot add te ...

In Typescript, it is not possible to utilize numbers or arrays within URLSearchParams

The method signature for appending to a URLSearchParams object in TypeScript is defined as append(name: string, value: string): void;. While I successfully appended an array and number in the browser, it resulted in an error when running the TypeScript co ...

Attach a unique anti-forgery identifier to XMLHttpRequest

Essentially, I am having an issue with validating the token in my JavaScript code. Everything works fine without validation, but once I try to validate the token, I receive an error stating The required anti-forgery form field "__RequestVerificationToken" ...

Leveraging Angular for Remote Configuration Management

How is everything going with you? I'm attempting to retrieve a configuration that I previously set up in Firebase's remote config using my Angular 15 application. The specific configuration is called "AllowedUsers." Here is the image of th ...

What is the process for converting an <input type="file> into a base64 string?

Currently, I'm attempting to send an image to my express backend by including the image directly in the post request body. var imgValue = document.getElementById("image").value; Within my post request: body : JSON.stringify({ image:imgValue ...

Is it feasible to utilize forkJoin in a similar manner to concat?

I am faced with a scenario where I have two observables - observableA and observableB. My goal is to create an observable that triggers only after both observableA and observableB have completed. Additionally, I want to subscribe to observableB only once ...

Can I display my clickCount without having to use the <input> tag for printing?

Is there a way to display my click count on the page without using an input element? Below is the code for reference: <!DOCTYPE html> <html> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <title> ...

JSON notation that spans multiple lines

Although there are many questions on this topic already, I am struggling to find the right solution for my specific case. Therefore, I have decided to move some user terms into a separate JSON file. These strings are quite lengthy. { "term&quo ...

Converting Angular object into an array

Is there a way to extract only the data array from the observable response? I'm interested in retrieving the values of cat_id, cat_name, and cat_description, but not the sql_types array. { "code": 0, "message": "" ...

Ways to assign a keyboard shortcut to an asp button

Q: Is there a way to detect when the user presses a specific key on their keyboard, similar to clicking a designated button? I'm looking to achieve this functionality because I have a grid view with an insert button in the gridview footer (to add a ...