I have a side dropdown menu that has three links with submenu items. When I am on one of those sub pages, i add a 'hover' class to the parent ul making it stay open. The problem is, when I hover over another menu link, that submenu still stays open, ultimately blocking the other submenu. How can I remove the hover class to the current link when i hover over another menu item and add it again if i hover out of it?
This is the code I tried to no avail
$(function(){
$(".dropdown-submenu.hover").toggleClass("active",true);
});
$(function(){
$(".dropdown-submenu").on("hover",function(e) {
if($(e.currentTarget).hasClass("active"))
$(e.currentTarget).toggleClass("active",false);
else
$(e.currentTarget).toggleClass("active",true);
e.preventDefault();
return false;
});
$(".dropdown-submenu").on("hide.bs.dropdown", doNothing);
$(".dropdown-submenu").on("show.bs.dropdown", doNothing);
function doNothing() {
e.preventDefault();
return false;
}
});
This is the html
<div class="hidden-xs dropdown col-sm-2 " id="sidebar" role="navigation">
<button id="mainnav" class="btn-block mainmenu mainnav dropdown-toggle" data-toggle="dropdown" data-autohide="false">Menu</button>
<ul id="mainsubnav" class="nav dropdown-menu mainsubnav" role="menu" aria-labelledby="dropdownMenu">
<li class="dropdown-submenu">Has Submenu 1
<ul class="dropdown-menu">
<li>Sublink 1</li>
<li>Sublink 1</li>
<li>Sublink 1</li>
</ul>
</li>
<li class="dropdown-submenu">Has Submenu 2
<ul class="dropdown-menu">
<li><a class="active" href="link1.php">Sublink 2</a></li>
<li>Sublink 2</li>
<li>Sublink 2</li>
</ul>
</li>
<li class="dropdown-submenu">Has Submenu 3
<ul class="dropdown-menu">
<li>Sublink 3</li>
<li>Sublink 3</li>
<li>Sublink 3</li>
</ul>
</li>
<li>Link</li>
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</div><!--/#sidebar-->
</div>
and this is the code that adds the hover class
$('ul.dropdown-menu > li > a.active:first').closest('li.dropdown-submenu').addClass('hover');
$('ul.dropdown-menu > li > a.active:first').closest('li.dropdown- submenu').children('a').addClass('active');
here is the example
http://www.bootply.com/hXsG8vzeDj
Related
I'm having a sliding menu with sub-menus. I'm trying to hide an element in the navigation row when a user clicks one of the parent menu item that has a sub-menu (clicks on the expand arrow) + I want to show back the hidden element when the users clicks back to the top-level menu.
My menu's <ul> element get's a class of slide-menu-is-active-parent when any of the sub-menus is open.
This is a simple version of my row html:
<div class="navigation row">
<nav>
<ul id="nav-menu">
<li>Menu item 1</li>
<span class="submenu-button">
<ul class="sub-menu">
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
<li>Menu item 2</li>
<span class="submenu-button">
<ul class="sub-menu">
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="content-row">
[whatever content...]
</div>
I tried the following script to add a class od menu-open to the some-content element when both conditions are met: the user clicks on the sub-menu button and when the <ul id="nav-menu"> element get's the slide-menu-is-active-parent class when opened. And with the class added to my content row, I could use simple .content-row.menu-open{display:none} to hide it.
function($) {
$("#nav-menu .submenu-button").click(function(){
if ($('#nav-menu').hasClass('slide-menu-is-active-parent')) {
$('.content-row').addClass('menu-open');
} else {
$('.content-row').removeClass('menu-open');
}
});
});
But that doesn't work. Any tips on where my script is lacking?
To be honest, your code works: just add the slide-menu-is-active-parent class to the #nav-menu, and the content-row shows up on click. Still, I would do this differently - even if using jQuery. Here's a simplistic solution:
jQuery(document).ready(function($) {
// this click handler opens the sub-menu
$(".menu-item").on('click', function() {
$(this).find(".sub-menu").toggle()
})
// this click handler toggles the content-row
$(".sub-menu > li").on('click', function(e) {
// stopPropagation prevents the click event
// to bubble up to the menu-item parent
e.stopPropagation()
$(".content-row").toggle()
})
})
.d-none {
display: none;
}
.menu-item,
.sub-menu>li {
cursor: pointer;
}
.content-row {}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="navigation row">
<nav>
<ul id="nav-menu">
<li class="menu-item">Menu item 1
<ul class="sub-menu d-none">
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
<li class="menu-item">Menu item 2
<ul class="sub-menu d-none">
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</li>
</ul>
</nav>
</div>
<div class="content-row d-none">
[whatever content...]
</div>
You need to use $(this) to refer to the element you clicked.
You also need to find parent with class, so you can use parents() with the name of your class.
NOTE : if i solved your problem, please next time do effort to make your question more clear, it will be better for everyone :)
$("#nav-menu .submenu-button").click(function(){
if ($(this).parents('#nav-menu').hasClass('slide-menu-is-active-parent')) {
$('.content-row').addClass('menu-open');
} else {
$('.content-row').removeClass('menu-open');
}
});
.content-row { display:none }
.menu-open { display:block }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="navigation row">
<nav>
<ul id="nav-menu" class="slide-menu-is-active-parent">
<li>Menu item 1</li>
<span class="submenu-button">Button</span>
<ul class="sub-menu">
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
<li>Menu item 2</li>
<span class="submenu-button">Button</span>
<ul class="sub-menu">
<li>Sub-menu item 1</li>
<li>Sub-menu item 2</li>
<li>Sub-menu item 3</li>
</ul>
</ul>
</nav>
</div>
<div class="content-row">
[whatever content...]
</div>
I am trying to make a sub-menu toggle on mobile but it keeps on redirecting to the parent menu link and adding event.preventDefault(); making entire sub-menu links unclickable. Any idea how to make only first .has-childern a link unclickable?
Markup
<div class="menu-container">
<ul class="nav-menu">
<li class="menu item"> Home </li>
<li class="menu-item has-childern"> About
<ul class="submenu">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li class="menu-item has-childern"> Services
<ul class="submenu">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li class="menu item"> Contact </li>
</ul>
</div>
jQuery
jQuery(document).ready(function(){
jQuery('.menu-container .submenu').hide();
jQuery('.menu-container .has-childern a').click(function() {
event.preventDefault();
jQuery(this).parent().children('.submenu').toggle();
});
});
JsFiddle https://jsfiddle.net/p5fLsvcq/
You code affect all nested children instead just direct child
use '>' for select just a direct first level child in selector:
jQuery('.menu-container .has-childern > a').click(/*...*/)
I have the following code:
<ul>
<li class="dropdown">
Select <span class="caret"></span>
<ul name="lstAddresses" class="dropdown-menu selectList__select js-address-list" role="menu">
<li value="0" selected="selected">address 1</li>
<li value="1">address 2</li>
...........
</ul>
</li>
</ul>
when first loaded, the dropdown is expanded. pressing the caret doesn't toggle the dropdown as I'd expect. What have I done wrong?
Is there a way to make submenu for sliding side menu?
JS Fiddle demo
<ul id="nav">
<li>Menu Item 1</li>
<ul id="submenu">
<li>Submenu Item 1</li>
<li>Submenu Item 2</li>
</ul>
<li>Menu Item 2</li>
</ul>
Fiddle DEMO
Changed Markup
added ul instead of li as ul can not directly contain ul
<div id="menu">
<ul>
<li>Menu Item 1
<ul id="submenu"> <!-- added ul instead of li -->
<li>Submenu Item 1
</li>
<li>Submenu Item 2
</li>
</ul>
</li>
<li>Menu Item 2
</li>
<li>Menu Item 3
</li>
</ul>
</div>
<div id="right">
<button type="button" id="button">Menu</button>
</div>
JS
$('#menu li:has("ul")').children('ul').hide(); //hide submenu
$('#button').toggle(
function () {
$('#right').animate({
left: 150
});
},
function () {
$('#right').animate({
left: 0
});
});
$('#menu li:has("ul")').click(function(){
$(this).children('ul').slideToggle(); //toggle submenu
});
References
.slideToggle()
:has()
I have a vertical sliding menu, that looks like this:
<ul class="menu">
<li>link</li>
<li>link</li>
<li class="more">link with submenu</li>
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
<li class="more">link with submenu</li>
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
<li>link</li>
<li>link</li>
</ul>
the jQuery is like this:
jQuery(document).ready(function($) {
$(".more").click(function() {
$(this).parent().children(".submenu").slideToggle(500); });
});
My problem is, when I click on a ".more", every ".submenu" is being slideToggle (Both opens)
How can I do, so it is only the correct submenu that is being slidetoggled?
Thank you.
Remove the call to .parent(). Also, your .submenu should be nested within the <li> to which it belongs, leaving you with the following jQuery:
$("li.more").on("click", function() {
$("ul.submenu", this).slideToggle(500);
});
And this markup:
<ul class="menu">
<li>link</li>
<li>link</li>
<li class="more">
link with submenu
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
</li>
<li class="more">
link with submenu
<ul class="submenu">
<li>sub link 1</li>
<li>sub link 2</li>
</ul>
</li>
<li>link</li>
<li>link</li>
</ul>
this one?
$(this).next().eq(0).slideToggle(500); });