Thursday, 2 June 2022

Utility function to toggle ARIA and data attributes, and manage CSS classes on HTML dropdowns

I have a dropdown utility function that is mostly working. The issues are with properly handling the toggling of the data-text and aria attributes for the buttons when clicking on the non-target button or outside the target element completely.

I have included my window.addEventListener code, but have commented it out as it is affecting the display of the ul sub menu elements.

I am learning vanilla JavaScript in bits and pieces, so please provide tips and solutions that are simple for a novice JS developer. Thanks.

const navUtility = (() => {
  const buttons = document.querySelectorAll("[data-nav-toggle]");
  const containers = document.querySelectorAll("[data-nav-container]");

  if (!buttons) {
    return;
  }

  function dropdownToggleHandler() {
    buttons.forEach((button) => {
      button.addEventListener("click", toggleContainer);
    });
  }

  function toggleContainer(e) {
    toggleButtonClass(e.target);
    toggleButtonAria(e.target);
    toggleButtonDataText(e.target);
    toggleContainers(e.target);
  }

  function toggleButtonClass(button) {
    if (button.classList.contains("is-active")) {
      button.classList.remove("is-active");
    } else {
      button.classList.add("is-active");
    }
  }

  function toggleButtonAria(button) {
    const expandedValue = button.getAttribute("aria-expanded");
    const setValue = expandedValue === "true" ? "false" : "true";
    button.setAttribute("aria-expanded", setValue);
  }

  function toggleButtonDataText(button) {
    const originalValue = button.getAttribute("data-text-original");
    const swapValue = button.getAttribute("data-text-swap");
    if (swapValue === button.textContent) {
      button.textContent = button.getAttribute("data-text-original");
    } else {
      button.setAttribute("data-text-original", button.textContent);
      button.textContent = button.getAttribute("data-text-swap");
    }
  }

  function toggleContainers(button) {
    const parent = button.closest("[data-nav-container]");
    parent.classList.toggle("is-expanded");
    document.querySelectorAll(".is-expanded").forEach(function(parentExpanded) {
      if (parentExpanded !== parent) {
        parentExpanded.classList.remove("is-expanded");
      }
    });
  }

  dropdownToggleHandler();

  /* window.addEventListener('click', function(e) {
    containers.forEach((container) => {
      if (e.target !== container) {
        container.classList.remove("is-expanded");
      }
    });
  }); */
})();
nav {
  position: relative;
}

nav>ul {
  width: 21rem;
  max-height: 0;
  position: absolute;
  right: auto;
  left: 0;
  z-index: 5;
  visibility: hidden;
  background-color: grey;
  transition: max-height 200ms ease-out;
}

nav.is-expanded>ul {
  max-height: 4000px;
  visibility: visible;
}
<nav class="" data-nav-container="want-to-navigation" aria-label="Site tools navigation">
  <button aria-expanded="false" class="" data-nav-toggle="want-to-navigation" data-text-swap="Close" data-text-original="I Want To...">Close</button>
  <ul id="want-to-navigation" class="menu">
    <li>
      <a>Apply For</a>
      <ul class="sub-menu">
        <li>
          <a href="#">Development Permits</a>
        </li>
        <li>
          <a href="#">Dust Suppressant</a>
        </li>
        <li>
          <a href="#">Fire Permit</a>
        </li>
        <li>
          <a href="#">Employment</a>
        </li>
        <li>
          <a href="#">Subdivision</a>
        </li>
      </ul>
    </li>
  </ul>
</nav>
<nav class="" data-nav-container="quick-links-navigation" aria-label="Site quick links navigation">
  <button aria-expanded="false" class="" data-nav-toggle="quick-links-navigation" data-text-swap="Close" data-text-original="Quicklinks">Close</button>
  <ul id="quick-links-navigation">
    <li>
      <a href="#">Community Guide</a>
    </li>
    <li>
      <a href="#">Notice of Development</a>
    </li>
    <li>
      <a href="#">Workshops &amp; Courses</a>
    </li>
    <li>
      <a href="#">Council Business</a>
    </li>
  </ul>
</nav>


from Utility function to toggle ARIA and data attributes, and manage CSS classes on HTML dropdowns

No comments:

Post a Comment