Switch the positive/negative signs of submenus when the main menu is toggled open or closed

Check out my custom jQuery menu implementation below, also available on JSfiddle here:

$(document).ready(function () {
    $(".main_menu_01, .main_menu_02").on('click', function () {
      var $panel = $(this).next('.panel');
      if ($panel.is(':visible')) {
        $panel.add($panel.find('.panel')).slideUp(500);
        $(this).hasClass('main_menu_01') ? $('.menu').removeClass('active') : $(this).removeClass('active');
      } else {
        $panel.slideDown(500);
        $(this).addClass('active');
      }
    });
});
.panel{ 
 width: 100%;
 padding-left: 0%;
 font-weight: bold;
 overflow: hidden;
 display:none;
}

.main_menu_01 {
 padding-left: 1%;
 background: blue;
}

.main_menu_02 {
 padding-left: 5%;
 background: lime;
}

.sub_menu_01{
 padding-left: 1%;
 background: lime;
}

.sub_menu_02{
 padding-left: 10%;
 background: lime;
}

 .main_menu_01:before, .main_menu_02:before {
 content:'+';
 width:20px;
 display:inline-block;
}

.main_menu_01.active:before, .main_menu_02.active:before {
 content:'-';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="menu main_menu_01"> 1.0 Main Menu </li>
  <ul class="panel">

    <li class="sub_menu_01"> 1.1 Sub Menu </li>

    <li class="menu main_menu_02"> 1.2 Sub Menu </li>
      <ul class="panel">
        <li class="sub_menu_02"> <a> 1.2.1 Sub Menu </a> </li>
        <li class="sub_menu_02"> <a> 1.2.2 Sub Menu </a> </li>
      </ul>
  </ul>
  
 
  
<li class="menu main_menu_01"> 2.0 Main Menu </li>
  <ul class="panel">

    <li class="sub_menu_01"> 2.1 Sub Menu </li>

    <li class="menu main_menu_02"> 2.2 Sub Menu </li>
      <ul class="panel">
        <li class="sub_menu_02"> <a> 2.2.1 Sub Menu </a> </li>
        <li class="sub_menu_02"> <a> 2.2.2 Sub Menu </a> </li>
      </ul>
 </ul>


I've encountered an issue with the functionality where toggling between menus changes signs from + to a -, as intended. However, when closing 1.0 Main Menu, both the submenu and the main menu signs change back to + instead of staying as -.

This inconsistency arises due to the code line $(this).hasClass('main_menu_01') affecting all classes with the name main_menu_01.

I'm currently facing difficulty in resolving this issue. Any suggestions on altering the code to achieve the desired behavior?

Answer №1

When dealing with multiple menus that share the same class, such as .menu, you can simplify your code by using this to target the specific menu you want to apply your function to. This way, the function will only affect the selected menu instead of all menus with the same class.

$(document).ready(function () {
    $(".menu").on('click', function () {
      $(this).next('.panel').slideToggle();
      $(this).toggleClass('active');
      if(!$(this).hasClass('active')){
        $(this).next('.panel').find('.panel').slideUp(); $(this).next('.panel').find('.menu').removeClass('active');
      }
});  
});
.panel{ 
 width: 100%;
 padding-left: 0%;
 font-weight: bold;
 overflow: hidden;
 display:none;
}

.main_menu_01 {
 padding-left: 1%;
 background: blue;
}

.main_menu_02 {
 padding-left: 5%;
 background: lime;
}

.sub_menu_01{
 padding-left: 1%;
 background: lime;
}

.sub_menu_02{
 padding-left: 10%;
 background: lime;
}

 .main_menu_01:before, .main_menu_02:before {
 content:'+';
 width:20px;
 display:inline-block;
}

.main_menu_01.active:before, .main_menu_02.active:before {
 content:'-';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="menu main_menu_01"> 1.0 Main Menu </li>
  <ul class="panel">

    <li class="sub_menu_01"> 1.1 Sub Menu </li>

    <li class="menu main_menu_02"> 1.2 Sub Menu </li>
      <ul class="panel">
        <li class="sub_menu_02"> <a> 1.2.1 Sub Menu </a> </li>
        <li class="sub_menu_02"> <a> 1.2.2 Sub Menu </a> </li>
      </ul>
  </ul>
  
  
  
<li class="menu main_menu_01"> 2.0 Main Menu </li>
  <ul class="panel">

    <li class="sub_menu_01"> 2.1 Sub Menu </li>

    <li class="menu main_menu_02"> 2.2 Sub Menu </li>
      <ul class="panel">
        <li class="sub_menu_02"> <a> 2.2.1 Sub Menu </a> </li>
        <li class="sub_menu_02"> <a> 2.2.2 Sub Menu </a> </li>
      </ul>
 </ul>

Answer №2

Ensure that you remove the active class only from the clicked menu and its sub menus, not all .menu elements. To achieve this, you can utilize $(this).next() followed by find('.menu') within that specific context.

$(document).ready(function() {
  $(".main_menu_01, .main_menu_02").on('click', function() {
    var $panel = $(this).next('.panel');
    if ($panel.is(':visible')) {
      $panel.add($panel.find('.panel')).slideUp(500);
      $(this).next().find('.menu').removeClass('active');
      $(this).removeClass('active');
    } else {
      $panel.slideDown(500);
      $(this).addClass('active');
    }
  });
});
.panel {
  width: 100%;
  padding-left: 0%;
  font-weight: bold;
  overflow: hidden;
  display: none;
}

.main_menu_01 {
  padding-left: 1%;
  background: blue;
}

.main_menu_02 {
  padding-left: 5%;
  background: lime;
}

.sub_menu_01 {
  padding-left: 1%;
  background: lime;
}

.sub_menu_02 {
  padding-left: 10%;
  background: lime;
}

.main_menu_01:before,
.main_menu_02:before {
  content: '+';
  width: 20px;
  display: inline-block;
}

.main_menu_01.active:before,
.main_menu_02.active:before {
  content: '-';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="menu main_menu_01"> 1.0 Main Menu </li>
<ul class="panel">

  <li class="sub_menu_01"> 1.1 Sub Menu </li>

  <li class="menu main_menu_02"> 1.2 Sub Menu </li>
  <ul class="panel">
    <li class="sub_menu_02"> <a> 1.2.1 Sub Menu </a> </li>
    <li class="sub_menu_02"> <a> 1.2.2 Sub Menu </a> </li>
  </ul>
</ul>



<li class="menu main_menu_01"> 2.0 Main Menu </li>
<ul class="panel">

  <li class="sub_menu_01"> 2.1 Sub Menu </li>

  <li class="menu main_menu_02"> 2.2 Sub Menu </li>
  <ul class="panel">
    <li class="sub_menu_02"> <a> 2.2.1 Sub Menu </a> </li>
    <li class="sub_menu_02"> <a> 2.2.2 Sub Menu </a> </li>
  </ul>
</ul>

Answer №3

Make sure to update the code to use $(this).find('.menu').removeClass('active') instead of $('.menu').removeClass('active').

$(document).ready(function () {
    $(".main_menu_01, .main_menu_02").on('click', function () {
      var $panel = $(this).next('.panel');
      if ($panel.is(':visible')) {
        $panel.add($panel.find('.panel')).slideUp(500);
        $(this).hasClass('main_menu_01') ? $(this).find('.menu').removeClass('active') : $(this).removeClass('active');
      } else {
        $panel.slideDown(500);
        $(this).addClass('active');
      }
    });
});
.panel{ 
 width: 100%;
 padding-left: 0%;
 font-weight: bold;
 overflow: hidden;
 display:none;
}

.main_menu_01 {
 padding-left: 1%;
 background: blue;
}

.main_menu_02 {
 padding-left: 5%;
 background: lime;
}

.sub_menu_01{
 padding-left: 1%;
 background: lime;
}

.sub_menu_02{
 padding-left: 10%;
 background: lime;
}

 .main_menu_01:before, .main_menu_02:before {
 content:'+';
 width:20px;
 display:inline-block;
}

.main_menu_01.active:before, .main_menu_02.active:before {
 content:'-';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="menu main_menu_01"> 1.0 Main Menu </li>
  <ul class="panel">

    <li class="sub_menu_01"> 1.1 Sub Menu </li>

    <li class="menu main_menu_02"> 1.2 Sub Menu </li>
      <ul class="panel">
        <li class="sub_menu_02"> <a> 1.2.1 Sub Menu </a> </li>
        <li class="sub_menu_02"> <a> 1.2.2 Sub Menu </a> </li>
      </ul>
  </ul>
  
  
  
<li class="menu main_menu_01"> 2.0 Main Menu </li>
  <ul class="panel">

    <li class="sub_menu_01"> 2.1 Sub Menu </li>

    <li class="menu main_menu_02"> 2.2 Sub Menu </li>
      <ul class="panel">
        <li class="sub_menu_02"> <a> 2.2.1 Sub Menu </a> </li>
        <li class="sub_menu_02"> <a> 2.2.2 Sub Menu </a> </li>
      </ul>
 </ul>

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

Seeking assistance with iterating through a specific JSON data structure

I am dealing with JSON data that has a specific format: {"errors":{"toDate":["Date error_message"],"name":["name error_message"]}} OR {"success":{"toDate":["Date update_data"],"name":["name update_data"]}} I am looking for a way to loop through this d ...

The arrival of chat featuring Ajax, long-polling, and support for multiple users has finally

Imagine a site with three modules: "links", "home", and "chat". The "links" and "home" modules are static pages that do not require long polling. However, in the "chat" module, new messages may arrive at any time from other users, requiring an immediate up ...

Deleting an element from HTML using jQuery

In the midst of creating a system that allows users to construct their own navigation structure, I have encountered a stumbling block. The idea is that when a user lands on the site, they are presented with a list of available topics from which they can ch ...

Utilizing the Jquery datetimepicker (xdsoft) to dynamically limit the date range between two inline datepickers

Check out the Jquery datepicker plugin available here: We previously had a setup where we could dynamically restrict the date range with two datepickers when text inputs are clicked on. However, the client now wants the calendars to be displayed inline, c ...

Can you provide instructions on how to adjust the width of a form using a JavaScript script within a CSS file?

I am currently working on creating a form where individuals can input their email addresses to receive some information. My goal is to design one HTML file that will work seamlessly on both desktop and mobile views by adjusting the form width based on th ...

Switch tabs with JavaScript

I'm encountering an issue with changing tabs using JavaScript and Ajax. The script I have works when not using Ajax but fails to work properly with it. Here is the script: $(document).ready(function(){ $("#mtabs li").click(function() { ...

<select> dropdown menu for selecting specific files opened by JavaScript

Currently, I am converting CSV files into JSON format and then manipulating them to generate arrays that will be used by jQuery to create a graph. My goal is to implement a dropdown menu that allows the user to choose a specific CSV file for graph creatio ...

Attempting to eliminate redundant data retrieved from an XML file being presented on my webpage

I need help deleting duplicate artists that appear when retrieving information from an XML file using JQuery. How can I achieve this? Check out the JS file below: $(function(){ $(window).load(function(){ $.ajax({ url: 'http://imagination ...

Steps for disabling automatic formatting in Visual Studio Code Version 1.35.1 with system setup

I am currently utilizing visual studio code for my Node JS application with mustache templating. In one of my HTML files, I have the following code: <script> {{{interface}}} </script> After the automatic formatting on save, it appears like t ...

Error encountered: syntax error, unexpected token while executing a basic AJAX request

Hello, I am new to AJAX and javascript, so please be patient with me. I am trying to pass a variable (document.getElementById('txtSearch').value) from my AJAX to PHP. Here is the code I attempted: $("#btnSearch").click(function() { ...

Create animations for SVG paths and polygons that move along specified paths

I am trying to animate both a path and a polygon in an SVG arrow along the same path. Currently, I have successfully animated the path using CSS, but I am struggling to figure out how to move the polygon along the path at the same pace. <svg id="La ...

Do my Dash tutorials appear drastically different from the documentation? Is this normal?

As an experienced back-end engineer, I am delving into the world of browser-based GUI design for the first time, specifically with HTML, CSS, and more. My current project involves building a dashboard using Dash, and I am in the early stages of familiarizi ...

When I incorporate the h-100 class, my content expands beyond the container on mobile devices

Struggling with implementing bootstrap 4.0? I'm attempting to utilize h-100 to ensure that the background stretches to the bottom of the user's screen. I've experimented with clearfix, fluid-containers, and more in an effort to make it work ...

Choosing the number of items for each cartItem in KnockoutJS: A comprehensive guide

Greetings! I am new to using knockout and I am attempting to automatically select the quantity for each item in my cart from a dropdown menu. Below is the code I have written: VIEW <div data-bind="foreach: cartItems"> <h3 data-bind="text: ful ...

Prevent dragging functionality after being dropped onto a droppable area

I am currently working on a drag and drop project and have encountered a minor issue. My goal is to disable the draggable item after it has been dropped onto the droppable area. I have created a function called disableDrag, but I am receiving an error in t ...

What is the method for transforming a portion of text from a website into HTML elements?

Currently, my workflow involves copying text from a webpage and then extracting the html tags. I go through the process of selecting the text, visiting wordtohtml.net, pasting it there, and finally copying the output with the necessary html tags and class ...

Arranging divs within a wrapper, ensuring that one of them displays a vertical scrollbar when the content exceeds the space available

I'm currently facing a challenge with defining the height of the description box in order to achieve the layout shown. I am trying to find a solution without relying on javascript. https://i.stack.imgur.com/3j278.png At present, the wrapper and titl ...

Waiting to run a function until a specified function has finished its execution

I have a piece of code that needs to address synchronization issues related to the execution order of MathJax functions. Specifically, I need to ensure that all the MathJax operations are completed before running the setConsoleWidth() function. What is t ...

Exploring the features of AngularJS with a secure login page

I need some guidance on the best way to create a login page. Currently, I have set up a ng-view root ("/login") in my app.js file. The issue I am facing with this approach is that I have to include static HTML in other files using ng-include. (This stati ...

Increasing the size of a card beyond the container using the CSS PRE tag

I am facing an issue with a card on my webpage. It contains a pre tag inside it, which is causing the size of the card to extend beyond its container, resulting in a horizontal scroll bar appearing. How can I make the content within the pre tag scroll hori ...