0

How can I amend this JavaScript code that will hide an open dropdown if another dropdown is selected? The original code came from the W3.CSS documentations, but I'm unsure of how to amend it. I tried replacing w3-show with w3-hide, tried removing and adding the classes within the JavaScript, but nothing seems to be doing the trick.

// Used to toggle the menu on small screens when clicking on the menu button
function myFunction() {
  var x = document.getElementById("mySidebar");
  if (x.className.indexOf("w3-show") == -1) {
    x.className += " w3-show";
    $('body').addClass("fixedPosition"); /* prevents page from scrolling when mobile navbar is open */
  } else {
    x.className = x.className.replace(" w3-show", "");
    $('body').removeClass("fixedPosition");
  }
}
//dropdowns on mobile nav
function myDropFunc(dropParam) {
  var x = document.getElementById(dropParam);
  if (x.className.indexOf("w3-show") == -1) {
    x.className += " w3-show";
    x.previousElementSibling.className += " w3-light-grey";
  } else {
    x.className = x.className.replace(" w3-show", "");
    x.previousElementSibling.className =
      x.previousElementSibling.className.replace(" w3-light-grey", "");
  }
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet" />
<div class="w3-sidebar w3-bar-block w3-card-2 w3-animate-right" style="width: 100%;" id="mySidebar">
  <div class="w3-panel w3-display-container w3-padding-large">
    <span onclick="myFunction()" class="w3-button w3-red w3-display-topright" style="margin-top: -22px;"><i class="fa fa-times fa-2x" aria-hidden="true"></i></span>
  </div>

  <div class="w3-dropdown-click w3-border-bottom">
    <button class="w3-button w3-padding-large w3-text-black w3-border-bottom" onclick="myDropFunc('it-services')">IT SERVICES <i class="fa fa-caret-down"></i></button>
    <div id="it-services" class="w3-dropdown-content w3-bar-block w3-card-2" style="z-index: 1000;">
      <a href="it-support" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">IT Support</a>
      <a href="managed-it-services" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Managed IT Services</a>
      <a href="network-design-and-administration" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Network Design and Administration</a>
      <a href="it-disaster-recovery" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">IT Disaster Recovery</a>
    </div>
  </div>
  <div class="w3-dropdown-click w3-border-bottom">
    <button class="w3-button w3-padding-large w3-text-black w3-border-bottom" onclick="myDropFunc('web-services')">WEB SERVICES <i class="fa fa-caret-down"></i></button>
    <div id="web-services" class="w3-dropdown-content w3-bar-block w3-card-2" style="z-index: 1000;">
      <a href="website-support-" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Website Support </a>
      <a href="web-design-package" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Web Design Package</a>
      <a href="affordable-seo" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Affordable SEO</a>
    </div>
  </div>
</div>
cweave
  • 306
  • 4
  • 13
  • Are you using jQuery? Asking as you have both jQuery selectors (`$('body')`) and vanilla javascript selectors (`document.getElementById`) in your functions. – agrm Nov 27 '17 at 16:00
  • Primarily vanilla JS, but can use jQuery as well. – cweave Nov 27 '17 at 16:04

1 Answers1

2

What you can do is hide all w3-dropdown-content before you show the dropdown that was clicked.

To do this you can amend myDropFunc(...) to close all content before it shows the clicked content

Here is the relevant piece of code to do this in that function. It gets all content by the classname w3-dropdown-content and iterates through each node to remove the w3-show class (whether it has it or not)

var allDropDownContent = document.getElementsByClassName("w3-dropdown-content");
for (var i = 0; i < allDropDownContent.length; i++) {
  allDropDownContent[i].className = allDropDownContent[i].className.replace(" w3-show", "");
}

and a full working example

// Used to toggle the menu on small screens when clicking on the menu button
function myFunction() {
  var x = document.getElementById("mySidebar");
  if (x.className.indexOf("w3-show") == -1) {
    x.className += " w3-show";
    $('body').addClass("fixedPosition"); /* prevents page from scrolling when mobile navbar is open */
  } else {
    x.className = x.className.replace(" w3-show", "");
    $('body').removeClass("fixedPosition");
  }
}
//dropdowns on mobile nav
function myDropFunc(dropParam) {
  // close all drop down content before showing clicked one.
  var x = document.getElementById(dropParam);
  if (x.className.indexOf("w3-show") == -1) {
    var allDropDownContent = document.getElementsByClassName("w3-dropdown-content");
    for (var i = 0; i < allDropDownContent.length; i++) {
      allDropDownContent[i].className = allDropDownContent[i].className.replace(" w3-show", "");
    }
    x.className += " w3-show";
    x.previousElementSibling.className += " w3-light-grey";
  } else {
    x.className = x.className.replace(" w3-show", "");
    x.previousElementSibling.className =
      x.previousElementSibling.className.replace(" w3-light-grey", "");
  }
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet" />
<div class="w3-sidebar w3-bar-block w3-card-2 w3-animate-right" style="width: 100%;" id="mySidebar">
  <div class="w3-panel w3-display-container w3-padding-large">
    <span onclick="myFunction()" class="w3-button w3-red w3-display-topright" style="margin-top: -22px;"><i class="fa fa-times fa-2x" aria-hidden="true"></i></span>
  </div>

  <div class="w3-dropdown-click w3-border-bottom">
    <button class="w3-button w3-padding-large w3-text-black w3-border-bottom" onclick="myDropFunc('it-services')">IT SERVICES <i class="fa fa-caret-down"></i></button>
    <div id="it-services" class="w3-dropdown-content w3-bar-block w3-card-2" style="z-index: 1000;">
      <a href="it-support" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">IT Support</a>
      <a href="managed-it-services" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Managed IT Services</a>
      <a href="network-design-and-administration" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Network Design and Administration</a>
      <a href="it-disaster-recovery" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">IT Disaster Recovery</a>
    </div>
  </div>
  <div class="w3-dropdown-click w3-border-bottom">
    <button class="w3-button w3-padding-large w3-text-black w3-border-bottom" onclick="myDropFunc('web-services')">WEB SERVICES <i class="fa fa-caret-down"></i></button>
    <div id="web-services" class="w3-dropdown-content w3-bar-block w3-card-2" style="z-index: 1000;">
      <a href="website-support-" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Website Support </a>
      <a href="web-design-package" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Web Design Package</a>
      <a href="affordable-seo" class="w3-bar-item w3-button w3-white w3-border-bottom w3-padding-large">Affordable SEO</a>
    </div>
  </div>
</div>
Andrew Lohr
  • 5,380
  • 1
  • 26
  • 38