Collapsing multiple navbar bootstrap - javascript

I have followed this example http://jsfiddle.net/rDN3P/98/ to create a collapsing navbar. It is working fine as long as I have one level in my menu. The collapsing seems not to work if I have multiple level of menu.
In this example, if you open the collapsible menu and click on the second 'dropdown2' item in the menu you will know what I mean.
This structure is the issue I assume
<li class="dropdown">
Dropdown <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Dropdown2
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li>Action sub</li>
</ul>
</li>

Solved: jsfiddle
Based on this answer to add the third level menu with a little modification of the js code to close the third level menu on click:
$('ul.dropdown-menu [data-toggle=dropdown]').on('click', function(event) {
// Avoid following the href location when clicking
event.preventDefault();
// Avoid having the menu to close when clicking
event.stopPropagation();
// If a menu is already open we close it
if($(this).parent().hasClass('open')){
$('ul.dropdown-menu [data-toggle=dropdown]').parent().removeClass('open');
}else{
// opening the one you clicked on
$(this).parent().addClass('open');
var menu = $(this).parent().find("ul");
var menupos = menu.offset();
if ((menupos.left + menu.width()) + 30 > $(window).width()) {
var newpos = - menu.width();
} else {
var newpos = $(this).parent().width();
}
menu.css({ left:newpos });
}
});

<li class="dropdown">
Dropdown <span class="caret"></span>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a href="#">
Dropdown2
</a>
<ul class="dropdown-menu" role="menu">
<li>Action sub</li>
</ul>
</li>
The nesting should be done properly I guess, with the correct classes.

Related

Bootstrap Navbar Toggler - Custom JS causes navbar menu to close on dropdown click

I'm new to JS and am in the process of learning while coding a website. I'm using a template that I found online with some custom modifications so I'm not super familiar with the JS used. Here is the issue.
While using the navbar toggler there is some custom JS to close the menu when the once a click happens in the menu. The issue is that I added a dropdown into the menu, and when it's clicked instead of showing the drop down details, the JS executes and closes the menu. here is the JS:
window.addEventListener('DOMContentLoaded', event => {
// Navbar shrink function
var navbarShrink = function () {
const navbarCollapsible = document.body.querySelector('#mainNav');
if (!navbarCollapsible) {
return;
}
if (window.scrollY === 0) {
navbarCollapsible.classList.remove('navbar-shrink')
} else {
navbarCollapsible.classList.add('navbar-shrink')
}
};
// Shrink the navbar
navbarShrink();
// Shrink the navbar when page is scrolled
document.addEventListener('scroll', navbarShrink);
// Activate Bootstrap scrollspy on the main nav element
const mainNav = document.body.querySelector('#mainNav');
if (mainNav) {
new bootstrap.ScrollSpy(document.body, {
target: '#mainNav',
offset: 74,
});
};
// Collapse responsive navbar when toggler is visible
const navbarToggler = document.body.querySelector('.navbar-toggler');
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive .nav-link')
);
responsiveNavItems.map(function (responsiveNavItem) {
responsiveNavItem.addEventListener('click', () => {
if (window.getComputedStyle(navbarToggler).display !== 'none') {
navbarToggler.click();
}
});
});
});
Only the bottom function is running the menu click/close function, but I provided all the code as for the custom menu actions as I'm not super familiar with JS. I understand, more or less, what it is doing, but I'm not sure how to modify it appropriately.
I'd imagine there is a simple way to modify that last "if" statement to check to see what was actually clicked (for example, if a .dropdown-menu was clicked). I just don't know how to use the code that is there and check what click caused the event trigger. I'd like to keep the close behavior when the .dropdown-items and other .nav-items are clicked. I just don't want the behavior when the .dropdown-menu is clicked.
Here is the html:
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav text-uppercase ms-auto py-4 py-lg-0">
<li class="nav-item"><a class="nav-link" href="#portfolio">Products</a></li>
<li class="nav-item"><a class="nav-link" href="#services">Services</a></li>
<li class="nav-item"><a class="nav-link" href="#how-to-order">How Order</a></li>
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">F.A.Q.</a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="dropdownMenuButton2">
<li><a class="dropdown-item" href="#">Knowledge Base</a></li>
<li><hr class="dropdown-divider"></li>
<li><h4 class="dropdown-header">Most Common Questions:</h4></li>
<li><a class="dropdown-item" href="#">Where are you located</a></li>
<li><a class="dropdown-item" href="#">How long is shipping</a></li>
<li><a class="dropdown-item" href="#">How do I pay</a></li>
<li><hr class="dropdown-divider"></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="#contact">Contact</a></li>
</ul>
</div>
I'm pretty sure this is a super simple JS problem that any coder worth his $.02 would know, but not knowing JS I don't even know where or what to search for. Any help?
The issue with your code is that when you are using querySelectorAll to access the nav-links the code is trying to access all the nav-links i.e., you are considering all the nav-links then the dropdown in your nav which is also a nav-link is also considered. So the better way to solve this is you can create a new class and attach it to the dropdown nav-link in your case F.A.Q and exclude that class from the function.
Your code:
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">F.A.Q.</a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="dropdownMenuButton2">
<li><a class="dropdown-item" href="#">Knowledge Base</a></li>
<li><hr class="dropdown-divider"></li>
<li><h4 class="dropdown-header">Most Common Questions:</h4></li>
<li><a class="dropdown-item" href="#">Where are you located</a></li>
<li><a class="dropdown-item" href="#">How long is shipping</a></li>
<li><a class="dropdown-item" href="#">How do I pay</a></li>
<li><hr class="dropdown-divider"></li>
</ul>
</li>
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive .nav-link')
);
You can add a class called faq and exlude it from the querySelectorAll using :not()
<!-- added a new class faq to the dropdown link -->
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle faq" data-bs-toggle="dropdown" role="button" aria-expanded="false">F.A.Q.</a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="dropdownMenuButton2">
<li><a class="dropdown-item" href="#">Knowledge Base</a></li>
<li><hr class="dropdown-divider"></li>
<li><h4 class="dropdown-header">Most Common Questions:</h4></li>
<li><a class="dropdown-item" href="#">Where are you located</a></li>
<li><a class="dropdown-item" href="#">How long is shipping</a></li>
<li><a class="dropdown-item" href="#">How do I pay</a></li>
<li><hr class="dropdown-divider"></li>
</ul>
</li>
// select all links except faq class
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive a.nav-link:not(.faq)')
);
Just add the below scripts within your tags, preferably before the closing tag
<!-- JavaScript -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

Set parent list item of dropdown link to active with jQuery / JavaScript (ASP.NET)

This is my menu
<ul class="sidebar-menu" id="navigation-menu">
<li class="active"><a class="nav-link" href="/"><i class="fas fa-home"></i><span>Home Page</span></a></li>
<li class="nav-item dropdown">
<i class="fas fa-cog"></i><span>Configuration</span>
<ul class="dropdown-menu">
<li><a class="nav-link" href="/Configuration/AccountCodes">Account Codes</a></li>
<li><a class="nav-link" href="/Configuration/Branches">Branches</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<i class="fas fa-person-booth"></i><span>Directory</span>
<ul class="dropdown-menu">
<li><a class="nav-link" href="/Directory/Users?Role=Administrator">Administrators</a></li>
<li><a class="nav-link" href="/Directory/Users?Role=Manager">Managers</a></li>
<li><a class="nav-link" href="/Directory/Users?Role=Agent">Agents</a></li>
</ul>
</li>
</ul>
This is my Jquery, when I select AccountCodes which is under the Configuration dropdown, it should only set the parent list item active. However, the Directory parent is set to active as well. I'm not sure how to select it directly.
Also, due to the structure of my URL, I am unable to continue to use endWith. Is there an alternate method of setting an active class based on the url? Currently, if I select AccountCodes or Branches, it correctly sets the Configuration dropdown item as active. However, If I select agent, nothing is selected at all due to its url ending with a ?Agent instead of Users
<script>
$(document).ready(function () {
var current = location.pathname;
console.log(current);
$("#navigation-menu a").each(function () {
var $this = $(this);
console.log($this.attr('href'));
if ($this.attr('href').endsWith(current)) {
console.log($this.parent());
$this.parent().addClass('active');
console.log("matched");
}
});
if ($(".dropdown-menu li").hasClass("active")) {
console.log("Yes");
var $this = $(this);
$(".dropdown-menu li").prev().parent().parent().addClass('active');
console.log($(".dropdown-menu li").closest(".nav-item dropdown"));
}
});
</script>
There would be two ways to mark only the parent link as active.
1. With jQuery
The advantage of this is that it will be compatible with any back end platform.
<script>
$(document).ready(function () {
var current = location.pathname;
console.log(current);
$("#navigation-menu a").each(function () {
var $this = $(this);
var link = $this.attr('href');
console.log(link);
// Remove the query string parameters by finding their starting position
var indexOfQueryString = link.lastIndexOf("?");
link = link.substring(0, indexOfQueryString);
if (link.endsWith(current)) {
console.log("matched");
if ($this.parent().parent().hasClass('.dropdown-menu')) {
var parentLink = $this.closest('.dropdown');
console.log("Setting parent link as active:", parentLink);
// Find the closest parent link and add active class
parentLink.addClass('active');
} else {
console.log("Setting link as active: ", $this.parent());
$this.parent().addClass('active');
}
}
});
});
</script>
In this case, as you have mentioned you encountered problems with ?Agent being present in link – this is what we refer to as query string parameters, which we can safely remove by searching for the unencoded question mark. This is already considered in the solution.
2. With ASP.NET MVC
Doing this in the back end would be more robust and should JavaScript be disabled by the user, this functionality will still work in your website. The disadvantage though, as you might have guessed, is that it is platform-dependent.
There are many ways of going about this. For your specific use-case, as your dropdown links are related to the parent by area, I have adapted another SO answer to cover your specific use-case:
public static string IsSelected(this HtmlHelper html, string area = "", string cssClass = "active")
{
ViewContext viewContext = html.ViewContext;
RouteValueDictionary routeValues = viewContext.RouteData.Values;
string currentArea = routeValues["area"] as string;
return area.Equals(currentArea) ? cssClass : String.Empty;
}
Then use it this way:
<ul class="sidebar-menu" id="navigation-menu">
<li><a asp-area="" asp-controller="Home" asp-action="Index" class="nav-link"><i class="fas fa-home"></i><span>Home
Page</span></a></li>
<li class="nav-item dropdown #Html.IsSelected(area: "Configuration")">
<i class="fas fa-cog"></i><span>Configuration</span>
<ul class="dropdown-menu">
<li><a asp-area="Configuration" asp-controller="AccountCodes" asp-action="Index" class="nav-link">Account
Codes</a></li>
<li><a asp-area="Configuration" asp-controller="Branches" asp-action="Index" class="nav-link">Branches</a>
</li>
</ul>
</li>
<li class="nav-item dropdown #Html.IsSelected(area: "Directory")">
<i class="fas fa-person-booth"></i><span>Directory</span>
<ul class="dropdown-menu">
<li><a asp-area="Directory" asp-controller="Users" asp-action="Index" asp-route-Role="Administrator"
class="nav-link">Administrators</a></li>
<li><a asp-area="Directory" asp-controller="Users" asp-action="Index" asp-route-Role="Manager"
class="nav-link">Managers</a></li>
<li><a asp-area="Directory" asp-controller="Users" asp-action="Index" asp-route-Role="Agent"
class="nav-link">Agents</a></li>
</ul>
</li>
</ul>
Would this benefit you, please make sure to upvote the other linked answer as well.

Active one main menu at a time hide others

please take a look at the image, here I am tried to do
If I click on "Fan Panels" The other two menus will be visible. Which is currently working fine. and here three menus will be visible.
If I click on "Entertain Art" menu the "Score Art" and "Fan Panels" need to be hidden, but the "Entertain Art" still need to show.
If I click on "Score Art" the "Fan Panels" and "Entertain Art" menu need to hidden, but the "Score Art" still need to show.
If you think about the code here it is :
{{#each categories}}
<li class="nav-list__item">
<a class="nav-list__item-link" href="{{url}}" title="{{name}}">{{name}}</a>
</li>
{/each}}
The website is under preview mode
Tts Big-commerce so menu displaying frontend with the dynamic syntax I think we can do it with javascript and jquery to find text and hide them what you suggest?
FOR EXAMPLE CODE:
<ul id="primeNav" class="nav-list nav-list--prime">
<li class="nav-list__item">
<a class="nav-list__item-link" href="#" title="Fan Panels">Fan Panels</a>
<li class="nav-list__item">
<a class="nav-list__item-link" href="#" title="Entertain Art">Entertain Art</a>
<li class="nav-list__item">
<a class="nav-list__item-link" href="#" title="Score Art">Score Art</a>
</ul>
Thanks in Advance
You can try this code alternatively -
Edit 3 -
Here's the newly updated code
/* Conditional Page Options */
var url = window.location.href;
var url = url.replace(/\//g, '');
var sub_url = location.protocol + location.host;
var page = url.replace(sub_url, '');
/* conditional click actions */
if (page == "entertain-art") {
$("#primeNav .nav-list__item").hide();
$("#primeNav .nav-list__item:nth-child(2)").show(); // revised
} else if (page == "score-art") {
$("#primeNav .nav-list__item").hide();
$("#primeNav .nav-list__item:nth-child(3)").show(); // revised
} else {
$("#primeNav .nav-list__item-link").on('click', function() {
var index = $(".nav-list__item-link").index(this);
if (index == 0) {
$("#primeNav .nav-list__item").show();
} else {
$("#primeNav .nav-list__item").hide();
$(this).parent().show();
}
});
}
$("#primeNav .nav-list__item:nth-child(4)").show(); // revised
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="primeNav" class="nav-list nav-list--prime">
<li class="nav-list__item">
<a class="nav-list__item-link" href="#" title="Fan Panels">Fan Panels</a>
</li>
<li class="nav-list__item">
<a class="nav-list__item-link" href="#" title="Entertain Art">Entertain Art</a>
</li>
<li class="nav-list__item">
<a class="nav-list__item-link" href="#" title="Score Art">Score Art</a>
</li>
</ul>
try it.
**UPDATE* : without adding new class name
//Without any new class name
$("#primeNav li").click(function(){
if($(this).text().trim()!="Fan Panels") //For Point 1, if click on FanPanel then show all
{
$("#primeNav li").hide(); // hide all item
$(this).show(); // Show item which is clicked
}
})
//Added **menu** as classname to all anchor tag, also added another unique class name to handle individual.
//Older try
$(".menu2").click(function(){
console.log($(this).text());
if($(this).hasClass("menuFan")==false) //For Point 1, if click on FanPanel then show all
{
$(".menu").hide(); // hide all item
$(this).show(); // Show item which is clicked
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="primeNav" class="nav-list nav-list--prime">
<li class="nav-list__item">
<a class="nav-list__item-link menu menuFan" href="#" title="Fan Panels">Fan Panels</a>
<li class="nav-list__item">
<a class="nav-list__item-link menu menuEnt" href="#" title="Entertain Art">Entertain Art</a>
<li class="nav-list__item">
<a class="nav-list__item-link menu menuScore" href="#" title="Score Art">Score Art</a>
</ul>

Auto Scroll Page + Close Sidebar After menu item select + Link Menu item with Section Ids(Wordpress - Jquery)

I am trying to create a custom sidebar menu...I have one page site with section on it...Every sidebar menu link should be connected to a specific section.I have created the menu but have two problems:
1) I want to link the menu items with sections ids with the help of jquery.
2) When user click on the menu item inthe sidebar,it should be closed automatically and scroll the page to that section.
I am new to Jquery and wordpress..Please help me to resolve this issue.
Sidebar Html:
<ul id="primary-menu" class="main-nav" role="menu">
<li class="menu-item menu-item-type-custom menu-item-object-custom">
<a href="#quote" data-level="1">
<span class="menu-item-text">
<span class="menu-text">Instant Quote</span>
<i class="underline"></i>
</span>
</a>
</li>
<li class="menu-item menu-item-type-custom menu-item-object-custom">
<a href="#ethos" data-level="1">
<span class="menu-item-text">
<span class="menu-text">Ethos</span>
<i class="underline"></i>
</span>
</a>
</li>
</ul>
Here is my Sidebar:
You have to give your section specific id like <section id="quote">
Then in your main.js write something
$('.menu-item').find('a').click(function(){
var $href = $(this).attr('href');
var $anchor = $($href).offset();
$('body, html').animate({ scrollTop: $anchor.top} ,1500);
return false;
});
For Closing the sidebar It depends on how you made this sidebar.

Href is not working on Edge or IE

I have this code,
<li class="centro-de-servicios col-md-3 col-xs-12 dropdown dropdown-toggle" data-toggle="dropdown">
<i class="icon-centro-de-servicios"></i>
Service Center <i class="arrow-down"></i>
<ul class="submenu dropdown-menu">
<li>Start</li>
<li>About Us</li>
<li>Our Policies</li>
<li>Maintenance</li>
<li>Quote a Visit</li>
<li>Service Tickets</li>
<!--<li></li>-->
<li>Advice</li>
<li>Contact</li>
</ul>
</li>
When i'm positioned on any element, and try to go to another page, the page is just refreshing, not changing. This happens only on Edge and IE.
I tried "window.location.href = 'url'", "location.href = 'url'", "location= 'url'", "location.replace('url')", etc, and there are not working, if a put a target blank it works, but i don't want the target blank.
You didn't close the url and put extra page="" in it.
Try it like this:
<li onclick = "location = 'http://beta.capris.cr/servicios/?page=centro-de-servicios&section=centro-deβ€Œβ€‹-servicios'">Start</li>
EDIT:
Have a look at this code on your page:
jQuery(".submenu a").click(function () {
jQuery(location).attr(jQuery(this).attr("href"));
location.reload();
// setTimeout(function () {
// updatePage(currentPage, location.hash);
// }, 10);
});

Categories