Clicking will close any other sub-menus

Greetings everyone, Thank you for taking the time to read through this post.

I am currently facing an issue while attempting to create a menu with sub-menus.

Here are the requirements for the menu:

  1. Sub-menus should open on click. (working)
  2. Selected sub-menus should remain open. (working)

    3. When clicking on other menus, previously opened sub-menus should close. (not working)

HTML

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <ul class="bottom-menu">
      <li class="drop"><a>Hyperlink 1</a></li>
      <li class="drop"><a>Hyperlink 2</a>
      <ul id="m1" class="bottom-menu-sub">
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
      </ul>
    </li>
    <li class="drop"><a>Hyperlink 3</a>
      <ul id="m2">
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
      </ul>
    </li>
    <li class="drop"><a>Hyperlink 4</a>
      <ul id="m3">
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
      </ul>
    </li>
</ul>

CSS:

      .bottom-menu li ul {
      display:none;
      }

JS:

jQuery(function ($) {
    // jQuery code in here can safely use $
    $('.bottom-menu li')
        .css({
        cursor: "pointer"
    });

    $(".drop>a").on('click', function (eventData) {
        var $listItem = $(this).closest('li');

        $listItem.find('ul').toggle();
        $listItem.toggleClass('open');

        $.cookie('open_items', 'the_value');
        openItems = new Array();
        $("li.drop").each(function (index, item) {
            if ($(item).hasClass('open')) {
                openItems.push(index);
            }
        });
        $.cookie('open_items', openItems.join(','));
    });

    if ($.cookie('open_items') && $.cookie('open_items').length > 0) {
        previouslyOpenItems = $.cookie('open_items');
        openItemIndexes = previouslyOpenItems.split(',');
        $(openItemIndexes).each(function (index, item) {
            $("li.drop").eq(item).addClass('open').find('ul').toggle();
        });
    }
});

Link to jsFiddle

Answer №1

Include the following code line:

$(".bottom-menu li").removeClass('open');

Here is the CSS to be added:

.bottom-menu li ul {
    display:none;
}
.bottom-menu li.open ul{
  display:block;
}

jQuery(function ($) {
        // jQuery code in here can safely use $
        $('.bottom-menu li')
            .css({
            cursor: "pointer"
        });

        $(".drop>a").on('click', function (eventData) {
        $(".bottom-menu li").removeClass('open');// Include This Line
            var $listItem = $(this).closest('li');

            $listItem.toggleClass('open');

            $.cookie('open_items', 'the_value');
            openItems = new Array();
            $("li.drop").each(function (index, item) {
                if ($(item).hasClass('open')) {
                    openItems.push(index);
                }
            });
            $.cookie('open_items', openItems.join(','));
        });

        if ($.cookie('open_items') && $.cookie('open_items').length > 0) {
            previouslyOpenItems = $.cookie('open_items');
            openItemIndexes = previouslyOpenItems.split(',');
            $(openItemIndexes).each(function (index, item) {
                $("li.drop").eq(item).addClass('open');
            });
        }
    });

Visit this link for reference

Answer №2

Flame has already pointed out the solution: closing everything with a click.

I made changes to your snippet by including

            $('.bottom-menu ul').each(function() { 
                $(this).hide();
            });

right after your click event (targets the bottom-menu class, loops through each unordered list within and hides it)

https://codepen.io/anon/pen/WXZaNe

Answer №3

Just wanted to provide some assistance.

jQuery(function ($) {
    // jQuery code below can utilize $

    $(".drop>a").on('click', function (eventData) {
        var $listItem = $(this).closest('li');
$('.drop ul').hide();
        $listItem.find('ul').toggle();
        $listItem.toggleClass('open');
        
        openItems = new Array();
        $("li.drop").each(function (index, item) {
            if ($(item).hasClass('open')) {
                openItems.push(index);
            }
        });
    });

    //if statement for cookies
});
.bottom-menu li ul {
    display:none;
}
.bottom-menu li{
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="bottom-menu">
    <li class="drop"><a>Hyperlink 1</a></li>
    <li class="drop"><a>Hyperlink 2</a>
      <ul id="m1" class="bottom-menu-sub">
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
      </ul>
    </li>
    <li class="drop"><a>Hyperlink 3</a>
      <ul id="m2">
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
      </ul>
    </li>
    <li class="drop"><a>Hyperlink 4</a>
      <ul id="m3">
        <li><a href="#">Hyperlink Sub</a></li>
        <li><a href="#">Hyperlink Sub</a></li>
      </ul>
    </li>
</ul>


<p>Explaining that opening "Hyperlink 2" displays the sub menu as intended, but selecting "Hyperlink 3" keeps the sub-menus of "Hyperlink 2" open.</br><p>

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

Show the comment section only if the initial radio button is selected

I am struggling to implement a comment section that is displayed when the first radio button is checked. Here's the code I have tried: I attempted the following to show the section and test the associated script: <div id="commentaryDiv" ...

I am puzzled as to why I keep receiving the error message "Cannot read property 'poPanel' of undefined"

CSS In my project, I am implementing a feature that displays an ordered list by looping through an array of objects and adding them on a button click. It works smoothly for adding items, but when I try to implement a remove function to delete each item, I ...

Fade-in a new, revised text after fading-out the original text in ReactJS

I have a bunch of p elements that I'd like to cycle through, fading in one at a time and then replacing it with the next. Here is the jQuery example on CodePen: https://codepen.io/motion333/pen/EBBGVM Now, I'm attempting to achieve the same effe ...

Similar route with identical element

Struggling to create a file renderer in the most efficient way possible. The current snippet I have seems quite repetitive: <Routes> <Route path='/explorer' element={<Files>}> <Route path=':root' element={< ...

When is it appropriate to utilize a view in EmberJS?

As a new user of EmberJS, I am navigating through the API and core components of the framework. One aspect that is challenging for me to fully comprehend is knowing when to utilize an Ember.View as opposed to an Ember.Component. My current understanding is ...

What could be the reason for the unexpected invisibility of the 4px margin on a static div?

I have a straightforward situation where I am using a fixed positioning <div> that spans the entire width with 100% width. It is designed to have a margin of 4px on all sides. However, for some reason, the right side margin is not visible. Can someon ...

Is your background image not filling the entire page?

Just diving into the world of HTML and CSS (with a touch of Bootstrap), I've set out to create a basic scrolling webpage. However, I've hit a roadblock with the background image not covering the full height of the page. It seems to stop at the h2 ...

Javascript timer that counts down using cookies for storage

Seeking assistance - I am in search of a solution to create a javascript countdown timer that utilizes cookies. I need the timer to remain consistent even when the user refreshes the page, until a specific time has elapsed. This is for an online examinat ...

Altering the value of a selection form element before sending off the data

Having trouble updating the select value upon submission. The system is rejecting special characters like "$" and ",", so I am cleaning up the data. Using jQuery jQuery("#vfb-53").val( jQuery("#vfb-53").val().replace(/\D/g,'') ); jQuery("# ...

Alignment issues with CSS3 navigation bar

After conducting thorough research on this topic, I realized that I am not alone in facing this issue. Unfortunately, the solutions provided by others with the same question did not resolve my problem. I have carefully configured my links for navigation wi ...

What is the best way to streamline these two JavaScript lines and eliminate redundancy?

In order to address an issue, I implemented the following two lines of code: MyString = div.getAttribute('data-type') || div.getAttribute('data-id'); MyString = MyString.replace('RemoveThis', ''); Although the code ...

The combination of Perlin Noise, Erlang, and JavaScript calls for a

Is it possible to generate the same noise map using a perlin/simplex noise generation algorithm with the same seed in two different programming languages? I am looking to create a procedurally generated multiplayer world where javascript clients and an er ...

SASS mixin that enables flexbox capabilities without supporting older, legacy versions of flexbox

Is it possible to provide support for browsers lacking flexbox compatibility (such as IE) while using SASS mixins? I have been quickly implementing the display:flex property with the following mixin. However, I am facing challenges with IE and need to man ...

Align the active li vertically within the ul

Looking to create a layout similar to musixmatch where the active verse is displayed at the center of the ul. https://i.sstatic.net/X7RV1.png I have experience doing this with JavaScript, but I'm curious if it's achievable using only CSS. < ...

Require assistance with an unoccupied Django dialog box

Looking to implement a popup in a django template, but encountering an issue where the popup appears empty. Below is the current code: <input type="button" value="{{ account.account_id }}" class="btn btn-primary" data-toggle="modal" data-target="#myMo ...

I utilized the "data-target" attribute to ensure the active link retains its style. Is there a way to preserve the style when navigating away from an active link?

Can someone assist me with this re-upload? I need help tweaking my code to maintain style when navigating between pages using the "data-target" attribute. Currently, the style is being lost when moving from the original link (e.g., "link/sub01.html") to a ...

Arranging elements in two arrays in either ascending or descending order

Looking to implement sorting functionality for the "fuel.name" value within this array... const orders = [ { "_id":"5d14a31490fb1e0012a3d2d8-1", "orderId":"0JL5ORM0JT-1", "created":"2019-06-27T11:05:56.377Z", "createdDate":"2019-06-2 ...

Tips for retrieving the HTML file of a modified canvas in HTML5

I’m currently working on a project to develop a website that allows users to design their own pages by simply dragging and dropping elements onto the canvas. The goal is for users to be able to save their creations as an HTML file. I’m facing challen ...

Why is it that my website in React crashes when I type rapidly in the TextField component?

Whenever I input text quickly into the TextField in my app, it causes my website to crash and display a blank white screen. Below is the snippet of code causing the problem: TextField Code: <TextField label="Item name" ...

Error encountered: `TypeError: Unable to access undefined properties (specifically, '0') within the Simple React Project`

Currently in the process of learning React and working on a simple photo application. Encountering an issue: Collection.jsx:6 Uncaught TypeError: Cannot read properties of undefined (reading '0') Why is this happening? Everything was functioni ...