Issue with Navbar Dropdown in Greyscale Template

First bug is that I was trying to post a bug report on Report a Bug but nothing happens when I press Submit. Second bug is here:

Hi Bootstrap Studio Team,

I hope this message finds you well. I would like to report an issue I encountered with the Greyscale template provided by Bootstrap Studio. The problem occurs when using a dropdown menu within the navbar. When the navbar is in the collapsed state (burger menu), clicking on a dropdown link causes the entire navbar to collapse.

After investigating, I identified the cause to be the attached JavaScript code that automatically collapses the navbar when any link is clicked. This behavior also affects dropdown links, which should be excluded from this functionality.

Here is the problematic JavaScript code from the template:

(function() {
“use strict”; // Start of use strict

var mainNav = document.querySelector(‘#mainNav’);

if (mainNav) {

var navbarCollapse = mainNav.querySelector('.navbar-collapse');

if (navbarCollapse) {

  var collapse = new bootstrap.Collapse(navbarCollapse, {
    toggle: false
  });
  
  var navbarItems = navbarCollapse.querySelectorAll('a');
  
  // Closes responsive menu when a scroll trigger link is clicked
  for (var item of navbarItems) {
    item.addEventListener('click', function (event) {
      collapse.hide();
    });
  }
}

// Collapse Navbar
var collapseNavbar = function() {

  var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;

  if (scrollTop > 100) {
    mainNav.classList.add("navbar-shrink");
  } else {
    mainNav.classList.remove("navbar-shrink");
  }
};
// Collapse now if page is not at top
collapseNavbar();
// Collapse the navbar when page is scrolled
document.addEventListener("scroll", collapseNavbar);

}

})(); // End of use strict

The issue can be resolved by modifying the event listener to exclude dropdown links from triggering the collapse. Here is the modified code:

(function() {
“use strict”; // Start of use strict

var mainNav = document.querySelector(‘#mainNav’);

if (mainNav) {

var navbarCollapse = mainNav.querySelector('.navbar-collapse');

if (navbarCollapse) {

  var collapse = new bootstrap.Collapse(navbarCollapse, {
    toggle: false
  });
  
  var navbarItems = navbarCollapse.querySelectorAll('a');
  
  // Closes responsive menu when a scroll trigger link is clicked
  for (var item of navbarItems) {
    item.addEventListener('click', function (event) {
      // Check if the clicked link is a dropdown toggle
      if (!event.target.classList.contains('dropdown-toggle')) {
        collapse.hide();
      }
    });
  }
}

// Collapse Navbar
var collapseNavbar = function() {

  var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement or document.body.parentNode or document.body).scrollTop;

  if (scrollTop > 100) {
    mainNav.classList.add("navbar-shrink");
  } else {
    mainNav.classList.remove("navbar-shrink");
  }
};
// Collapse now if page is not at top
collapseNavbar();
// Collapse the navbar when page is scrolled
document.addEventListener("scroll", collapseNavbar);

}

})(); // End of use strict

I hope this helps in addressing the issue. Thank you for providing such a great tool, and I look forward to seeing this improvement in future updates.

Best regards,

Frits

@fritslyneborg

If you want the mobile nav to collapse when click an anchor link in the dropdown menu, you can do something like this.

The code is straightforward and commented, the comments are helpful in explaining the purpose of each section of the code. They clarify what each part of the code is doing, making it easier to understand the functionality of the script.

document.addEventListener('DOMContentLoaded', function () {
  'use strict';
	
	// Global constans
  const mainNav = document.getElementById('mainNav');
  const mobileNav = document.getElementById('navbarResponsive');
  const scrollThreshold = 100;

	// Scrollhandler to shrink the navbar
  function scrollHandler() {
    const shouldShrink = window.scrollY > scrollThreshold;
    mainNav.classList.toggle('navbar-shrink', shouldShrink);
  }

	// Selector for navbarlinks and dropdown menus
  const narbarLinks = mainNav.querySelectorAll(
    '.nav-link a:not(dropdown-toggle), .dropdown-item'
  );
	
	// EventListener for the navbar links
  narbarLinks.forEach((link) =>
    link.addEventListener('click', () => {
      if (mobileNav.classList.contains('show'))
        bootstrap.Collapse.getOrCreateInstance(mobileNav).hide();
    })
  );

	// EventListeners
  document.addEventListener('scroll', scrollHandler);
  document.addEventListener('resize', scrollHandler);
});

Here’s a breakdown:

  1. DOMContentLoaded Event Listener: The script starts by listening for the DOMContentLoaded event, which fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. This ensures that the JavaScript code runs only after the HTML document is fully loaded.

  2. Global Constants: Global constants are defined for elements such as the main navigation (mainNav), the mobile navigation (mobileNav), and a scroll threshold (scrollThreshold). These constants are used throughout the script to reference these elements without repeating the code.

  3. Scroll Handler Function: A function named scrollHandler is defined to handle the scrolling behavior. It checks whether the window has scrolled beyond a certain threshold (scrollThreshold) and then toggles a class (navbar-shrink) on the mainNav element accordingly.

  4. Navbar Links Selector: Navbar links are selected using querySelectorAll. This selector targets all anchor elements within .nav-link classes that are not dropdown toggles, as well as all elements with the .dropdown-item class.

  5. Navbar Links Event Listeners: Event listeners are attached to each navbar link using forEach. These event listeners trigger a function that checks if the mobile navigation is currently shown (mobileNav has the class show), and if so, hides it when a link is clicked.

  6. Event Listeners: Event listeners are added to the scroll and resize events on the document object. These event listeners call the scrollHandler function whenever the user scrolls or resizes the window.

Why on earth are you explaining me this when I am trying to file a bug report on a theme, and even myself shows whats wrong and how to fix it?

The post made by @kuligaposten does not negate your bug report. I believe he was simply trying give you a quick solution to your problem, since it may take the developers some time to investigate this.

It’s not a bss bug, the Grayscale template bss use is an old version of the template and it doesn’t has support for dropdowns in the navbar.

In the grayscale.js there are depricated issues and you are using them as well.

Even if the devs update the template to the current version which is V7.0.6 it still not support for dropdowns and you will face the same issue with the dropdown in the navbar.
You can have a look at the current version here

The script I posted above is just one way how you can fix the issue

1 Like