Close all flyout menus in Bootstrap 4 Menu when the top menu item is closed

This Bootstrap 4 menu has an unconventional structure with three levels. The third level menus are managed by jQuery, but there's a problem - they remain open even after the top menu item is closed. I'm using jQuery to eliminate the need for clicking on the menus to reveal the sub-menus, which has made things quite messy. Unfortunately, I can't modify the HTML because it's generated by a menu walker.

Query: Is there a way to close all flyout menu items and their submenus (like 27028) when the top-level menu item (3381) is closed?

Question: Also, how can I get rid of the redundant click needed on a menu item (like 27028) to display the submenu items?

Check out this fiddle: https://jsfiddle.net/s04ezjhr/

<ul id="menu-main-menu-admin" class="navbar-nav"><li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement" id="menu-item-3381" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children nav-item menu-item-3381 dropdown">
<a title="Human Resources" href="#" data-toggle="dropdown" class="nav-link dropdown-toggle" aria-haspopup="true">Human Resources <span class="caret"></span></a>
<ul role="menu" class=" dropdown-menu" >
<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement" id="menu-item-27077" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-27077"><a title="Test Link" href="#" class="dropdown-item">Test Link</a></li>
<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement" id="menu-item-27028" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-27028 dropdown"><a title="HR Reports" href="#" data-toggle="dropdown" class="nav-link dropdown-toggle" aria-haspopup="true">HR Reports <span class="caret"></span></a>
<ul role="menu" class=" dropdown-menu" >
<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement" id="menu-item-27029" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-27029"><a title="Change Of Status" href="https://example.com/change-of-status/" class="dropdown-item">Change Of Status</a></li>
<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement" id="menu-item-27031" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-27031"><a title="Failure To Start" href="https://example.com/failure-to-start/" class="dropdown-item">Failure To Start</a></li>
<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement" id="menu-item-27032" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-27032"><a title="Intent To Hire" href="https://example.com/intent-to-hire/" class="dropdown-item">Intent To Hire</a></li>
</ul>
</li>
</ul>

The current jQuery code that handles third-level menu items and "show on hover" submenus:

$('.dropdown-menu a.dropdown-toggle').on('click', function(e) {
  if (!$(this).next().hasClass('show')) {
    $(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
  }
  var $subMenu = $(this).next(".dropdown-menu");
  $subMenu.toggleClass('show');

  $(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function(e) {
    $('.dropdown-submenu .show').removeClass("show");
  });
  return false;
});


function toggleDropdown (e) {
  const _d = $(e.target).closest('.dropdown'),
    _m = $('.dropdown-menu', _d);
  setTimeout(function(){
    const shouldOpen = e.type !== 'click' && _d.is(':hover');
    _m.toggleClass('show', shouldOpen);
    _d.toggleClass('show', shouldOpen);
    $('[data-toggle="dropdown"]', _d).attr('aria-expanded', shouldOpen);
  }, e.type === 'mouseleave' ? 300 : 0);
}

$('body')
  .on('mouseenter mouseleave','.dropdown',toggleDropdown)
  .on('click', '.dropdown-menu a', toggleDropdown);

Answer №1

The issue with the current script is that it triggers all dropdown menus to open when hovered over. To resolve this, you can modify it so that only the immediate child dropdown menu opens.

function toggleDropdown(e) {
  const _d = $(e.target).closest('.dropdown'),
    _m = $('> .dropdown-menu', _d);
  setTimeout(function() {
    const shouldOpen = e.type !== 'click' && _d.is(':hover');
    _m.toggleClass('show', shouldOpen);
    _d.toggleClass('show', shouldOpen);
    $('[data-toggle="dropdown"]', _d).attr('aria-expanded', shouldOpen);
  }, e.type === 'mouseleave' ? 300 : 0);
}

$('body')
  .on('mouseenter mouseleave', '.dropdown', toggleDropdown)
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="85f5eaf5f5e0f7abeff6c5b4abb4b3abb5">[email protected]</a>/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>


<ul class="navbar-nav" id="menu-main-menu-admin">
  <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children nav-item menu-item-3381 dropdown" id="menu-item-3381" itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement">
    <a aria-haspopup="true" class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" title="Human Resources">
            Human Resources
            <span class="caret">
            </span>
        </a>
    <ul class="dropdown-menu" role="menu">
      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-27077" id="menu-item-27077" itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement">
        <a class="dropdown-item" href="#" title="Test Link">
                    Test Link
                </a>
      </li>
      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-27028 dropdown" id="menu-item-27028" itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement">
        <a aria-haspopup="true" class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" title="HR Reports">
                    HR Reports
                    <span class="caret">
                    </span>
                </a>
        <ul class="dropdown-menu" role="menu">
          <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-27029" id="menu-item-27029" itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement">
            <a class="dropdown-item" href="https://example.com/change-of-status/" title="Change Of Status">
                            Change Of Status
                        </a>
          </li>
          <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-27031" id="menu-item-27031" itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement">
            <a class="dropdown-item" href="https://example.com/failure-to-start/" title="Failure To Start">
                            Failure To Start
                        </a>
          </li>
          <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-27032" id="menu-item-27032" itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement">
            <a class="dropdown-item" href="https://example.com/intent-to-hire/" title="Intent To Hire">
                            Intent To Hire
                        </a>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Answer №2

Attention Required in Your Code!

The necessary modifications are outlined below:

  1. Make sure to close all HTML tags properly in your code.

    Add the following lines at the end of the file: </li> </ul>

  2. Include a Bootstrap script file in your code as Bootstrap 4 requires it.

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>

Implement these changes in your code for proper functionality

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

The $.ajax POST method successfully sends data to the server, but the $.ajax PUT method fails to do so

When utilizing jQuery to make an ajax call, I observed that using the POST method works perfectly fine. However, when switching to the PUT method without any other alterations, the object data is not being sent. This has led me to the question of why this ...

Updating image on click in CSS and HTML

How can I change the image to display a different picture when clicked? I currently have a green image that, upon clicking, switches pages and transforms into a white image. Before Click https://i.sstatic.net/wBVCL.png After Click https://i.sstatic.net/Z ...

Tips for eliminating flicker upon the initial loading of a webpage caused by dynamic changes in CSS styles through JavaScript

Struggling with the load order of my CSS and JavaScript... Currently, I have a div with a blue background that is styled to appear sliced diagonally. However, upon initial page load (or CTRL+SHIFT+R), there's a brief moment where the slice effect doe ...

Navigating the DOM with jQuery and iterating through tables without specific IDs

Coldfusion and CF markup code can be ignored as this is a jQuery question. In the table below, which can be looped over up to 200 times, users can enter a system name into the 'System Name' field and click the "CHECK" button. This triggers an aj ...

ajax response is equal to zero

For the past two days, I have been attempting to solve a problem on my own. However, I am now seeking assistance as I seem to be stuck. The task at hand is quite straightforward - a jQuery AJAX request sends a username and password to a server running the ...

Error occurred during deployment on Vercel: "Compilation Failed. Module cannot be found: Error encountered when trying to resolve './app.css' in '/vercel/path0/src'"

When attempting to deploy my React app on Vercel, I encountered an error during the build process. Here is the error message that appeared: https://i.sstatic.net/alxAG.png I attempted to resolve the issue by capitalizing app.css to App.css, but unfortunat ...

RStudio Connect now automatically inserts CSS code into cells when updating

My current project involves creating an app for holiday requests. The main page of the app is displayed like this: https://i.sstatic.net/z2qma.png At the bottom right corner, you'll notice a column labeled "Accepted?" which displays either "OK" or " ...

Having difficulty with CSS animation and background issues

I can't seem to get my rotating background to work using CSS keyframe animation. I've tried different things but can't figure out what's going wrong. Below is my code: .main-header { width: 100%; Height: 128px; } .main-header, ...

Having trouble updating the DataTable with extra details retrieved from a new URL

I'm currently utilizing the DataTable plugin. After loading the DataTable, my aim is to reload the table, while keeping the existing content intact, and adding information gathered from a separate json file. However, I'm encountering an issue wh ...

How can the horizontal scroll bar width be adjusted? Is it possible to create a custom

Within my div, I have implemented multiple cards that scroll horizontally using the CSS property: overflow-x: scroll; This setup results in a horizontal scrollbar appearing under the div, which serves its purpose. However, I would prefer a customized scr ...

JavaScript tag filtering system: Display only the div elements that contain all the specified classes in an array; otherwise, hide them

Can you provide some guidance on accomplishing this task? I am looking to toggle the visibility of a div based on its classes and an array. If the array contains the term something, then only divs with the class something will be displayed. If the array ...

What is a clear indication that a <div> is filled with text?

Picture a scenario where a website contains an element that needs to be filled with random text using JavaScript. Once the div is completely filled, it should reset and begin again. It may sound odd, but the question is: how will the JavaScript determine w ...

Preventing a keyboard from appearing when buttons are pressed

Ever created a tool that inserts text into a <textarea> using button inputs? You can check out mine here But here's the issue - on mobile devices, when users tap those buttons, the keyboard covers half of the screen. Any solutions to prevent th ...

What causes my email HTML to display incorrectly in Outlook?

Check out the HTML email fiddle I've put together: HTML Email Fiddle The design is looking good on Gmail, Hotmail, and Outlook Web, but it's a disaster in Outlook Client. See the screenshot below for proof: https://i.sstatic.net/JkdPh.png I&apo ...

Using JQuery to calculate and store user-inputted values in CodeIgniter

I'm working on an inventory management application with Codeigniter, and I need to calculate the total price when a user enters quantity and unit price. However, the values are not being saved to the database with the current implementation. Any advic ...

Guide on duplicating an HTML element's markup and style completely

Looking for a Chrome tool that can extract both the HTML and relevant CSS code of an element along with its child elements. Any suggestions? ...

Unable to retrieve function variables stored in fancytree source nodes within its activate method

If the configuration of my fancytree includes a source like this: source: [{ title: "Item1", key: "1", myFunc: function (item) { return 'function'; ...

Guide to pinpointing a location with Google Maps

I am currently working on setting up a contact page that includes Google Maps to show the location of a meeting place. Here is the code I am using: JavaScript (function(){ document.getElementById('map_canvas').style.display="block"; var ...

Utilize JavaScript and PHP to dynamically modify the contents of an HTML file

After not receiving a satisfactory answer to my question yesterday, I decided to find a solution. However, I am now facing an issue with the new program and unsure of the mistake. The program involves retrieving the contents of announcement.html and displ ...

Strange glitch in the Trebuchet MS font

I am currently attempting to utilize the jquery.fullcalendar plugin with jQuery UI theming. Everything seems to be functioning properly, except for an issue where the user's selection of a time range (week or day view) is displaced by approximately on ...