Tapping on the Child Component will automatically close the currently opened list

Recently, I created a menu that expands to show all child elements when clicking on the parent menu link. However, I encountered an issue where clicking on a child element collapses the menu. You can view a demo of my implementation here: http://codepen.io/anon/pen/KzpKrm. My goal is to have the list expand and indicate the selected link when clicking on a child element. If anyone has a solution, please help me out!

  function showmenu(elem) {
        // Clear any currently open menu
        var openMenu = document.getElementById("activeMenu");
        if (openMenu) {
            openMenu.removeAttribute("id");
            // Stop if we're just closing the current menu
            if (openMenu === elem) {
                return;
            }
        }

        // Only apply it if the element actually has LI child nodes.
        // OPTIONAL: Will still work without if statement.
        if (elem.getElementsByTagName("li").length > 0) {
            elem.setAttribute("id", "activeMenu");
        }
    }

Answer №1

If you want to prevent bubbling, simply include event.stopPropagation() within the nested ul:

<ul id="nav">
    <li onclick="showmenu(this)" class="sectionMenu">
        Service
        <ul onclick="event.stopPropagation()">
            <li><a> Ro </a>    </li>
            <li> <a>List</a> </li>
            <li><a>Service Plan</a> </li>
        </ul>
    </li>
    ....
</ul>

Answer №2

To determine if the element clicked is a parent (having the class sectionMenu), you can implement the following JavaScript logic:

// Check if the element clicked has the class 'sectionMenu'. If not, exit.
var $elementClicked = event.target;
if ($elementClicked.className !== 'sectionMenu') {
  return;
}

CodePen

function showmenu(elem) {

    // Check if the element clicked has the class 'sectionMenu'. If not, exit.
    var $elementClicked = event.target;
    if ($elementClicked.className !== 'sectionMenu') {
      return;
    }
  
    // Clear any currently open menu
    var openMenu = document.getElementById("activeMenu");
    if (openMenu) {
      openMenu.removeAttribute("id");
      // Stop if we're just closing the current menu
      if (openMenu === elem) {
        return;
      }
    }

    // Apply only if the element actually has LI child nodes.
    // OPTIONAL: Will still work without this if statement.
    if (elem.getElementsByTagName("li").length > 0) {
      elem.setAttribute("id", "activeMenu");
    }
  }
img {
         padding-left: 5px;
       }
       #nav {
         height: 100%;
         padding: 20px;
         cursor: pointer;
         border: 3px solid #3e4547;
         box-shadow: 2px 2px 8px #000000;
         border-radius: 3px;
         -moz-border-radius: 3px;
         -webkit-border-radius: 3px;
       }
       ul {
         width: 200px;
         list-style: none;
         margin: 0;
         padding: 5px;
       }
       ul li {
         display: block;
         padding: 0 10px;
         overflow: hidden;
         padding: 5px;
       }
       ul ul {
         display: none;
       }
       ul ul li {
         float: none;
         user-select: #b6ff00;
       }
       #activeMenu ul {
         display: block;
       }
       ul li:hover {
         background-color: #bcbdc1;
       }
       ul ul li:hover {
         background-color: red;
       }
       .arrow {
         background-image: url("./png/2.png");
         transition: 0.3s;
         transform: rotateX(-180deg);
       }
       li.sectionMenu:before {
         content: '\2795';
         font-size: 13px;
         color: #777;
         float: right;
         margin-left: 5px;
       }
       li.sectionMenu#activeMenu:before {
         content: "\2796";
       }
<div>
  <ul id="nav">
    <li onclick="showmenu(this)" class="sectionMenu">
      Service
      <ul>
        <li><a> Ro </a> 
        </li>
        <li> <a>List</a> 
        </li>
        <li><a>Service Plan</a> 
        </li>

      </ul>
    </li>
    <li onclick="showmenu(this)" class="sectionMenu">
      Customer
      <ul>
        <li>New Customer</li>
        <li>customer List</li>

      </ul>
    </li>
    <li onclick="showmenu(this)" class="sectionMenu">
      Parts
      <ul>
        <li>New Part</li>
        <li>Parts List</li>

      </ul>
    </li>
    <li onclick="showmenu(this)" class="sectionMenu">
      Admin
      <ul>
        <li>New Employee</li>
        <li>Employee List</li>
        <li>Employee Roles</li>
        <li>Employee Work Schedulee</li>
        <li>Holidays</li>

        <li>Employee List</li>

      </ul>
    </li>
  </ul>
</div>

Answer №3

Give it a shot. Don't forget to include the event argument for the onclick handlers

function displayMenu(element, event) {
        // Clear any currently open menu
        event.preventDefault();
        // alert(event.currentTarget.getAttribute("id"))
        var currentMenu = document.getElementById("activeMenu");

        if (currentMenu) {
            if(currentMenu.children[0]==event.target.parentNode)
              return;
            currentMenu.removeAttribute("id");
            // Stop if we're just closing the current menu
            if (currentMenu === element) {
                return;
            }
        }

        // Only apply it if the element actually has LI child nodes.
        // OPTIONAL: Will still work without if statement.
        if (element.getElementsByTagName("li").length > 0) {   
          event.currentTarget.setAttribute("id", "activeMenu");
        }
    }

CodePen

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

Ajax dropdown menu displaying 'Loading Data' message during processing

Is it possible to display a Please wait.. or Loading... label underneath my Combo box while data is loading? I would like to show a Loading... message under the switch box when switching between Male and Female. https://i.sstatic.net/zpFDF.jpg This is th ...

Design a section with a blue background for better form organization

I am striving to develop a section similar to this: enter image description here. It will be an area where users can input information for authentication or create an account. I have already crafted a PHP form connected to my database as shown below: <f ...

Can the coordinates in an array be constrained within a specific radius?

I am relatively new to using Google Maps and ReactJS. To plot my map, I am utilizing google-maps-react. The property I am working with is comprised of multiple polygons that collectively form the property (farm) displayed on the map. Upon clicking a spec ...

The sequence of execution in php compared to POST method in HTML

Despite understanding the order of execution, I am still puzzled about how POST works as an HTML command. Since PHP executes before HTML, how do PHP variables receive data from POST unless they are sent to a separate file? I know that using $_SERVER[&apos ...

Incorporating and designing a side button using jQuery Mobile

I'm working on adding a button to the left side of the screen that is round (but not necessarily) and partially visible, with a visually appealing design. This button will allow users to open a side menu panel. Below is the HTML code for the button: ...

Guide to writing a Jasmine test case to verify Toggle class behavior within a click event

My directive is responsible for toggling classes on an element, and it's working as expected. However, I seem to be encountering an issue with the jasmine test case for it. // Code for toggling class fileSearch.directive('toggleClass', func ...

Unlimited digest loop in Angular.js caused by nested ng-repeat and filter

In my AngularJS project, I have developed a custom filter that categorizes elements by type and performs a search for multiple search terms across all attributes of devices. angular.module('abc').filter('searchFor', function(){ return ...

Encountering issues with React Apollo hooks after integrating React Native into the monorepo system

I am in the process of setting up a React web app and a React-native app within a monorepo using yarn workspaces. The web and controllers are functioning properly, allowing me to successfully execute graphql queries to my apollo-express server. However, up ...

How can I deactivate Bootstrap specifically within a certain block of content?

Is there a way to deactivate Bootstrap within a specific section? I want the styles from Bootstrap's CSS file to be overridden inside this div. ...

Disable system discord.js

Hey there, I'm experiencing an issue with my code and could use some help. Every time I try to use my mute command, it keeps spamming "You need permission to use command". Below is the snippet of my code: client.on('message', message => { ...

Is there a way to compare timestamps in PostgreSQL using moment.js and focus only on the date aspect?

I've encountered a small issue that has me stumped - I'm trying to figure out the best solution for it. The problem lies in a table I have, with attributes named "Start" and "End". My objective is to store every row in an array where the "Start" ...

Creating a fading effect on an image in relation to another dynamic image

I am currently facing an issue in my code where I am trying to make one image fade in next to another, regardless of the position of the movable image on the screen. The movable image can be controlled using arrow keys, and when I move it across the screen ...

What is the best way to place multiple images on top of one another within a single div, and make them break apart with animation upon hovering?

HTML: <div class="mySlides"> <img src="1.jpg"> <img src="2.jpg"/> <img src="3.jpg"/> <img src="4.jpg"/> <img src="5.jpg"/> </div> CSS: .mySlides { padding-top: 25%; padding-left: 5%; ...

What is the proper way to connect an external Javascript file to an html document within a Play Framework project?

Below is the content of my scala.html file: @() <!DOCTYPE html> <html> <head> <title> Spin To Win </title> <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/styles.css")" ...

Angular: Navigating to another URL causes the page to revert back to the default route

Currently, I am working with Angular 1.3.10, ui-router 0.2.10, and Express 4.14.0 to develop a Reddit-style application, and I'm facing some issues with routing. The simplified version of my Express routes: router.get('/api/home', function ...

Attempting to develop a straightforward JavaScript presentation display

The slideshow will cycle through six images named 1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg, and 6.jpg var showarray = ["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg"]; var i = 0; for( i = 0; i < 6; i++) { // Is there a way to pause the script for two ...

Creating dynamic data for Chart.js to display values

I am attempting to utilize dynamic data using ajax, but my current implementation is not functioning correctly. The ajax response returns data in JSON format via PHP. Here is the code snippet: success: function (result) { result = JSON.parse(r ...

Prevent incomplete date input in Html5 date input field

Is it possible to make an input type="date" field, which is not required, treat partially completed dates entered by the user (e.g. month and day without year) as invalid rather than silently accepting them? I would like to alert the user in this scenari ...

Discovering all the links present on a webpage using node.js

Currently, I am diving into node.js (webdriver) and encountering some challenges. Despite my efforts to search online for examples of the tasks I need help with, I have come up empty-handed. One example that has me stumped is how to log all links from a pa ...

Script - Retrieve the content of the code element

I am currently developing an extension for VS Code that will enhance Skript syntax support. One challenge I am facing is the inability to select the body of the code block. Skript syntax includes various blocks such as commands, functions, and events, eac ...