Hiding dropdown menu on hover issues - javascript

I can see that this question has been asked a bit although I've found no solution that fixes my specific problem.
I have a sub menu within a menu that doesn't work as intended, it simply needs to be shown when hovered over and then when it's not hovered over, hide the sub menu.
Right now I can hover over the menu item but then when I got to select the next option it disappears.
I don't know where I'm going wrong, I know it's a simple feature yet it's driving me mad! here's my working below:
$(document).ready(function() {
$('.dropdown-submenu a.subhover').on("mouseover", function(e) {
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
});
$(document).ready(function() {
$('.dropdown-submenu a.subhover').on("mouseleave", function(e) {
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
});
.dropdown-submenu {
position: relative;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
display: hidden;
}
.dropdown-submenu:hover .dropdown-menu {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="dropdown menu-btn">
<a id=t estmanage class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-database fa-lg "></i> Manage <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a id="btn_addnew" href="#">Create Audit</a></li>
<li>Departments</li>
<li>Products</li>
<li class="dropdown-submenu">
<a class="subhover" tabindex="-1" href="#"> Data Entry <span class="caret"></span></a>
<ul style="display: none;" class="dropdown-menu">
<li> Labour Costs </li>
<li> Purchases </li>
<li style="cursor: pointer;"><a data-toggle="modal" data-target="#salesModal">Sales</a></li>
<li> Wastage </li>
</ul>
</li>
</ul>
</li>
Forgive me for the formatting of the HTML part, can't get it to look like how it displays on my editor!

This can be done using CSS-Only. Just take a look at my solution:
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
display: none;
}
.subhover:hover ~ .dropdown-menu, .dropdown-menu:hover {
display: block;
}
<li class="dropdown menu-btn">
<a id=t estmanage class="dropdown-toggle" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-database fa-lg "></i> Manage <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a id="btn_addnew" href="#">Create Audit</a></li>
<li>Departments</li>
<li>Products</li>
<li class="dropdown-submenu">
<a class="subhover" tabindex="-1" href="#"> Data Entry <span class="caret"></span></a>
<ul class="dropdown-menu">
<li> Labour Costs </li>
<li> Purchases </li>
<li style="cursor: pointer;"><a data-toggle="modal" data-target="#salesModal">Sales</a></li>
<li> Wastage </li>
</ul>
</li>
</ul>
</li>
And in this fiddle, both dropdowns are working together: https://jsfiddle.net/thau2g9j/13/

It's not working because you are executing same lines of code on mouseover and mouseleave. The below code is not required. Comment and check, if that should suffice you requirement.
$(document).ready(function() {
$('.dropdown-submenu a.subhover').on("mouseleave", function(e) {
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
});
Below is the running code snippet:
$(document).ready(function() {
$('.dropdown-submenu a.subhover').on("mouseover", function(e) {
$(this).next('ul').toggle();
e.stopPropagation();
e.preventDefault();
});
});
//$(document).ready(function() {
// $('.dropdown-submenu a.subhover').on("mouseleave", function(e) {
// $(this).next('ul').toggle();
// e.stopPropagation();
// e.preventDefault();
// });
//});
.dropdown-submenu {
position: relative;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
display: hidden;
}
.dropdown-submenu:hover .dropdown-menu {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="dropdown menu-btn">
<a id=t estmanage class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-database fa-lg "></i> Manage <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a id="btn_addnew" href="#">Create Audit</a></li>
<li>Departments</li>
<li>Products</li>
<li class="dropdown-submenu">
<a class="subhover" tabindex="-1" href="#"> Data Entry <span class="caret"></span></a>
<ul style="display: none;" class="dropdown-menu">
<li> Labour Costs </li>
<li> Purchases </li>
<li style="cursor: pointer;"><a data-toggle="modal" data-target="#salesModal">Sales</a></li>
<li> Wastage </li>
</ul>
</li>
</ul>
</li>

Related

How to close toggle when next list is toggled

This is a multi-child dropdown menu, Actually I am trying to toggle a menu one at a time (i.e. only selected menu will show other should close).
Here is my code
HTML
<div class="collapse navbar-collapse pull-left" id="navbar-collapse">
<ul class="nav navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">Master<span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a class="test" tabindex="-1" href="#">MENU-A<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">A1-CHILD</a></li>
<li><a tabindex="-1" href="#">A2-CHILD</a></li>
</ul>
</li>
<li class="dropdown-submenu">
<a class="test" tabindex="-1" href="#">MENU-B<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">B1-CHILD</a></li>
<li><a tabindex="-1" href="#">B2CHILD</a></li>
</ul>
</li>
<li class="dropdown-submenu">
<a class="test" tabindex="-1" href="#">MENU-C <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a class="test" href="#">C1-CHILD <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>C1-A</li>
<li>C1-B</li>
</ul>
</li>
<li class="dropdown-submenu">
<a class="test" href="#">C2-CHILD <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>C2-A</li>
<li>C2-B</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
JS:
$(document).ready(function{
$(".dropdown-submenu a.test").on("click", function(e){
$(this).next("ul").toggle();
e.stopPropagation();
e.preventDefault();
});
});
CSS:
.dropdown-submenu {
position: relative;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
}
This didn't close after another menu toggles and the third level of submenu didn't flexible for the first answer.
thanks,
You need to get closest ul where click event has occur then using .not() exclude it from hiding and then simply use next("ul").toggle(); to show dropdown menu .
Demo code :
$(document).ready(function() {
$(".dropdown-submenu a.test").on("click", function(e) {
//get closest `li`-> ul
var selector = $(this).closest(".dropdown-submenu").find("ul");
//hid all other li and ul
$(".dropdown-submenu ul").not(selector).not(this.closest('ul')).hide()
$(this).next("ul").toggle(); //show this a-> next ul
e.stopPropagation();
e.preventDefault();
});
});
.dropdown-submenu {
position: relative;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-top: -1px;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="collapse navbar-collapse pull-left" id="navbar-collapse">
<ul class="nav navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">Master<span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a class="test" tabindex="-1" href="#">MENU-A<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">A1-CHILD</a></li>
<li><a tabindex="-1" href="#">A2-CHILD</a></li>
</ul>
</li>
<li class="dropdown-submenu">
<a class="test" tabindex="-1" href="#">MENU-B<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">B1-CHILD</a></li>
<li><a tabindex="-1" href="#">B2CHILD</a></li>
</ul>
</li>
<li class="dropdown-submenu">
<a class="test" tabindex="-1" href="#">MENU-C <span class="caret"></span></a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a class="test" href="#">C1-CHILD <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>C1-A</li>
<li>C1-B</li>
</ul>
</li>
<li class="dropdown-submenu">
<a class="test" href="#">C2-CHILD <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>C2-A</li>
<li>C2-B</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>

bootstrap toggle dropdown from within javascript

I have a bootstrap 4 dropdown menu that expands (toggles) on hover instead of a click. On a click a link is followed. (I know, this is bad practice). Now I am trying to achieve that on touch-enabled devices, the link is never followed and on a click or touch the dropdown is toggled.
I have managed to disable the link, but I can't seem to toggle the menu. This is what I tried:
JS
var button = jQuery('.btn-dropdown-link');
if ('ontouchstart' in window) {
button.click(function (e) {
e.preventDefault();
console.log('clicked / touched');
jQuery('#dropdownMenuButton').dropdown('toggle'); // this does not work?
});
}
HTML
<ul>
<li class="btn dropdown" id="dropdownMenuButton" aria-haspopup="true" aria-expanded="false">
<a class="btn btn-dropdown-link dropdown-toggle" href="/com">some link</a>
<ul class="dropdown-menu" id="dropdownDonateMenu" aria-labelledby="dropdownMenuButton">
<li>example</li>
<li>example</li>
<li>example</li>
</ul>
</li>
</ul>
CSS
.dropdown:hover > .dropdown-menu {
max-height: 500px;
opacity: 1;
}
.dropdown .dropdown-menu {
transition: all 0.3s;
max-height: 0;
display: block;
overflow: hidden;
opacity: 0;
min-width: 100%;
}
Or a live example on codeply.
How can I toggle the dropdown when I use e.preventDefault(); to block the link?
Edit: I have to use JS
You can add the :active on css on the same place you have the :hover
and on the HTML you can simply remove the href
something like this on the CSS:
.dropdown::active > .dropdown-menu, .dropdown::active > .dropdown-menu {
max-height: 500px;
opacity: 1;
}
and on the HTML you can simply remove the
You can do that using d-**-none and d-**-block on the break point which you wanna show
.dropdown:hover>.dropdown-menu {
display: block;
width: fit-content;
}
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<ul class="navbar-nav ml-auto">
<li class="nav-item dropdown" style="cursor:pointer">
<a class="nav-link d-none d-sm-none d-md-none d-lg-block dropdown-toggle" id="navbarDropdown3" data-hover="dropdown" aria-haspopup="true" aria-expanded="false" href="/com">dropdown</a>
<a class="nav-link d-lg-none dropdown-toggle" id="navbarDropdown3" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" href="/com">dropdown</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown3">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>

Adding second child to dropdown menu

Im experiencing an issue adding a second child to the drop-down-menu.
here is my html code:
<ul class="sidenav sidenav-fixed" id="nav-mobile">
<li>
<a onclick="load('file-name')"><i class="material-
icons">home</i>TEXT
</a>
</li>
<div class="divider"></div>
<li><a onclick="load('file-name')"><i class="material-
icons">apps</i>TEXT</a>
</li>
<li><a onclick="load('file-name')"><i class="material-
icons">copyright</i>Copyright</a>
</li>
<li class="button-dropdown">
<a onclick="load('file-name') class="dropdown-toggle"><i class="material-
icons">assignment</i>Unit A<i class="fa fa-angle-right changed"></i>
</a>
<ul class="dropdown-menu" style="display: none;">
<li>
<a onclick="load('file-name')">Menu 1</a>
</li>
</ul>
<ul class="dropdown-menu" style="display: none;">
<li>
<a onclick="load('file-name')">Menu 2</a>
</li>
</ul>
</li>
</ul>
and here is my js:
jQuery(document).ready(function (e) {
$(".dropdown-toggle").click(function () {
$(this).parents(".button-dropdown").children(".dropdown-
menu").toggle().parents(".button-dropdown").children(".dropdown-
toggle").addClass("active")
});
$('.dropdown-toggle').on('click', function () {
$(this)
.find('.changed')
.toggleClass('fa-angle-down')
.toggleClass('fa-angle-right');
});
});
Here are the styles applied for drop-down-menu:
.dropdown-menu li > a {
text-align: center;
}
.dropdown-menu li:hover > a {
background-color: #385170 !important;
color: #fff !important;
}
.changed {
margin-left: 5px;
}
I need to add another child under Menu 1 and Menu 2.
Thanks a lot for your help.
The first issue I found in your code is that you are defining the same event twice, which means that only the last one will be executed.
To append items with jQuery inside an event listener is as easy as:
Keeping code clean.
Globals at the beginning of your code:
var buttonDropdown = $(".button-dropdown");
And then your event listener for dropdown-toggle click:
$('.dropdown-toggle').on('click', function () {
buttonDropdown.append("<li>new item</li>");
});
This will append a new item to button-dropdown everytime you click dropdown-toggle.
Here is an example:
var buttonDropdown = $(".button-dropdown");
jQuery(document).ready(function (e) {
$('.dropdown-toggle').on('click', function (event) {
let itemNumber = buttonDropdown.children().length;
buttonDropdown.append("<ul><li>Menu "+itemNumber+"</li></ul>");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="sidenav sidenav-fixed" id="nav-mobile">
<li>
<a onclick="load('file-name')">
<i class="material- icons">home</i>TEXT
</a>
</li>
<div class="divider"></div>
<li>
<a onclick="load('file-name')">
<i class="material- icons">apps</i>TEXT
</a>
</li>
<li>
<a onclick="load('file-name')">
<i class="material- icons">copyright</i>Copyright
</a>
</li>
<li class="button-dropdown">
<a onclick="load('file-name')" class="dropdown-toggle">
<i class="material- icons">assignment</i>Unit A
<i class="fa fa-angle-right changed"></i>
</a>
<ul class="dropdown-menu" style="display: block;">
<li>
<a onclick="load('file-name')">Menu 1</a>
</li>
</ul>
<ul class="dropdown-menu" style="display: block;">
<li>
<a onclick="load('file-name')">Menu 2</a>
</li>
</ul>
</li>
</ul>
Note: This example is made from the context you provided. If it still not solves your entire issue, feel free to edit your question and comment here so I can update mine with the requirements for your question.
And also, you did not provide any styles for your code, that's why it looks so plain.

Bootstrap 4 - Keeping Parent of Dropdown a clickable link

<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
New to bootstrap. Here's the code based on the Bootstrap example. Right now the dropdown shows up but you're not able to click on the dropdown itself. I want to be able to make all the parent nav links work. Similar to this website: https://eastcfashion.com/
Where clicking on for example: men's collection brings you to all the collection for that area. But the dropdown menu, you're able to just go on specific items.
I'm trying to implement it in a way that the main parent nav would say Projects. and the dropdown menu for projects would show specific pages for each project like project 1, project 2, etc. But clicking on Projects would take you to a page where project 1, project 2, and the collection of projects would be showing as a group and not individually.
jQuery(function($) {
if ($(window).width() > 769) {
$('.navbar .dropdown').hover(function() {
$(this).find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();
}, function() {
$(this).find('.dropdown-menu').first().stop(true, true).delay(100).slideUp();
});
$('.navbar .dropdown > a').click(function() {
location.href = this.href;
});
}
});
#media only screen and (min-width:769px) {
.dropdown:hover .dropdown-menu {
display: block;
}
.dropdown-submenu {
position: relative !important;
}
.dropdown-submenu>.dropdown-menu {
top: 0 !important;
left: 100% !important;
margin-top: -6px !important;
margin-left: -1px !important;
border-radius: 0 !important;
}
.dropdown-submenu:hover>.dropdown-menu {
display: block !important;
}
.dropdown-submenu>a:after {
display: block;
content: "\f105";
font-family: 'FontAwesome';
margin-top: -18px;
right: 15px;
position: absolute;
font-weight: 300;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://v4-alpha.getbootstrap.com/dist/js/bootstrap.min.js"></script>
<link href="https://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet" />
<nav class="navbar navbar-toggleable-md navbar-light bg-faded">
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li><li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="http://example.com" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown link
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
The easiest way to do it is by deleting the "data-toggle" attribute from the parent element!
edit: thx for the tip, here is a code example:
I changed this:
<a class="p-2 text-dark dropdown-toggle" data-toggle="dropdown" style="font-size:1.25rem;" href= {% url 'link' %}>Link</a>
to this:
<a class="p-2 text-dark dropdown-toggle" style="font-size:1.25rem;" href= {% url 'link' %}>Link</a>
so, in essence, I simply deleted the data toggle attribute and thus converted a hoverable dropdown into a hoverable dropdown with a clickable parent link.
I tried to keep the code simple. My solution is to detect the second click on the dropdown button/link and follow the link at that point.
$('.navbar .dropdown > a').click(function() {
if (!$(this).hasClass("parent-clicked")) {
$(this).addClass("parent-clicked");
} else {
location.href = this.href;
}
});
This works in the collapsed view as well.
I took Joe's answer and improved it to my needs
/*
* Only go to the link when dropdown is already open (if the dropdown is a link)
*/
$('.navbar ul.navbar-nav > .dropdown > a[href]').click(function() {
var dropdown = $(this).next('.dropdown-menu');
/*
* The dropdown can be non-existent
* The dropdown can be already open by css
* (for instance display: block from a custom :hover setting)
* or a "show" class on the element which also sets a display: block;
*/
if (dropdown.length == 0 || $(dropdown).css('display') !== 'none') {
if (this.href) {
location.href = this.href;
}
}
});
The Bootstrap 4 html for this is
<header class="navbar">
<ul class="nav navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link" href="/planning" data-toggle="dropdown">
Planning
</a>
<ul class="dropdown-menu">
<li class="dropdown-item">
Day planning
</li>
</ul>
</li>
</ul>
</header>
Clickable dropdown link in Bootstrap 4
I hide the original dropdown triangle icon and make a new plus icon because the original icon is very small and made with pseudo-class :after, it's hard for user to point the cursor and click it.
So the parent href link will work as normal but when user click on plus icon it will open the dropdown.
/* -----------------------------------------------------------------------
Make Bootstrap dropdown "a" link clickable
But when clicking plus icon, show the dropdown
--------------------------------------------------------------------------- */
function clickableDropdownLink() {
if (window.matchMedia("(max-width: 992px)").matches) {
const dropdownToggle = $('.navbar .dropdown > a');
dropdownToggle.append('<span class="dropdown-icon"></span>');
dropdownToggle.removeAttr('data-toggle');
$('.navbar .dropdown > a').click(function(e) {
e.preventDefault();
if ((e.target.tagName == 'A')) {
const route = $(this).attr("href");
window.location.href = route == '/' || route == '#' ? window.location.href : route;
return;
}
})
const dropdownIcon = $('.navbar .dropdown > a > span.dropdown-icon');
dropdownIcon.click(function() {
const parentLink = $(this).parent("a.nav-link");
parentLink.parent(".nav-item").toggleClass("show");
parentLink.next(".dropdown-menu").toggle();
})
}
}
clickableDropdownLink();
/* ------------------------------------------------------------------------------------
This is optional, this could make your app slower
If you want to make a dropdown link clickable after user resizing screen, you can add this. This could make your app slower
----------------------------------------------------------------------------------------- */
$(window).resize(function() {
clickableDropdownLink();
})
/* ------------------------------------------------------------------------------------
This is optional
If you also want the dropdown link work in Desktop size.
----------------------------------------------------------------------------------------- */
if (window.matchMedia("(min-width: 992px)").matches) {
$('.navbar .dropdown > a').click(function() {
location.href = this.href;
});
}
.dropdown .dropdown-icon{
display: none;
position: absolute;
padding: 15px;
background: #fff;
right: 10px;
top: 8px;
}
.dropdown .dropdown-icon:before{
transition: all ease 0.5s;
background: #444;
height: 2px;
width: 16px;
top: 14px;
left: 7px;
content: "";
position: absolute;
}
.dropdown .dropdown-icon:after{
transition: all ease 0.5s;
background: #444;
content: "";
height: 16px;
left: 14px;
position: absolute;
top: 7px;
width: 2px;
}
.dropdown.show .dropdown-icon:after{
transform:rotate(-90deg);
}
.dropdown.show .dropdown-icon:before{
transform:rotate(-180deg);
}
.navbar .dropdown .dropdown-toggle .dropdown-icon{
display:none;
}
#media(max-width:992px){
.navbar .dropdown .dropdown-toggle::after{
display:none;
}
.navbar .dropdown .dropdown-toggle .dropdown-icon{
display:block;
}
.navbar .dropdown .dropdown-menu .dropdown-item{
white-space:pre-wrap;
}
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Clickable Dropdown Link</title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css'><link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="https://www.google.com" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown1
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action 1</a>
<a class="dropdown-item" href="#">Another action 1</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here 1</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="https://www.google.com" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.1/umd/popper.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js'></script><script src="./script.js"></script>
</body>
</html>
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a>
This snippet toggles the dropdown but on click event and href is used to toggle the dropdown menu. So According to your need -
Redirect href to the general project page and add hover event to display the dropdown menu using jquery or CSS.To display the Dropdown menu just add open class to <li class="nav-item dropdown">
Using CSS,
Using Jquery
Here is my solution. The idea is to detect the area that the user clicked on the dropdown button/link and redirect to that url.
// clickable dropdown menu parent
$('.navbar .dropdown > a').on('click', function(e) {
let elementBegin = $(this).offset()['left']; // get link position X
// get the width of the menu by text's length
// you need to contain the text inside a span tag
let spanWidth = $(this).find("> span").width();
let clickAreaLength = spanWidth * 0.9; // 90% of width = clickable area
let clickPositionX = e.pageX; // position of the click
// if click position is inside the clickable area, then redirect
if (clickPositionX < elementBegin + clickAreaLength) {
location.href = this.href;
}
});
This works in the collapsed view (mobile) as well.
//Fix bootstrap dropdown parent click
let clicked = 0;
document.querySelector('.dropdown-toggle').addEventListener('click',(e)=>{
clicked++;
if(clicked > 1 && e.target.classList.contains('show')){
location.href = e.target.href
clicked = 0;
}
})
Simple javascript only solution, second click on parent will redirect to location IF dropdown contains the open class.

How to add active class only on second level of the navigation

I have an vertical navigation with two levels.
What I want is when I press the main li to add active and open class just to the main li and when I press on the sub-menu I want to add active just to that li. Here is my code:
HTML
<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
<li class="start active open">
<a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li class="active">
<a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li>
<a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li>
<a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li>
<a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
</ul>
JS
$(".sub-menu li").on("click", function() {
$(".sub-menu li").removeClass("active");
$(this).addClass("active");
});
$(".page-sidebar-menu li").on("click", function() {
$(".page-sidebar-menu li").removeClass("active open");
$(this).addClass("active open");
});
You have to target the closest li inside class .page-sidebar-menu
$(".sub-menu li").on("click", function() {
$(".sub-menu li").removeClass("active");
$(this).addClass("active");
});
$(".page-sidebar-menu > li").on("click", function() {
$(".page-sidebar-menu > li").removeClass("active open");
$(this).addClass("active open");
});
i'm not sure if i understood exactly what you asked.
But, from what i get i remade your html a bit (added a menu class to bind the click event more precisely)
<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
<li class="menu start active open"> <a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li class="active"> <a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li> <a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
<li class="menu"> <a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li> <a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li> <a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
</ul>
And so my version of your jQuery looks like that :
$(document).ready(function () {
// added a menu class to bind the click event more precisely
$(".menu > a").on("click", function () {
// nothing is active but this
$(".active").removeClass("active");
// and close the other menus
$(".menu").removeClass("open");
$(this).parent().addClass("active open");
});
$(".sub-menu li").on("click", function () {
// nothing is active but this
$(".active").removeClass("active");
$(this).addClass("active");
});
});
The CSS i used to test it was just this :
.menu { display: block; }
.sub-menu { display: none; }
.open, .open .sub-menu { display: block; }
.active { text-transform: uppercase; }
For an example, go check that jsfiddle that i made to answer you (really basic css here) and tell me if that's what you asked for.

Categories