Skip to content

Instantly share code, notes, and snippets.

@lysender
Last active August 17, 2023 05:57
Show Gist options
  • Save lysender/bc9800e6350e1ccfab3c6ce6934b1cd2 to your computer and use it in GitHub Desktop.
Save lysender/bc9800e6350e1ccfab3c6ce6934b1cd2 to your computer and use it in GitHub Desktop.
HTMX - Toggle Hamburger Menu for mobile browsers

How to toggle hamburger menu on/off in HTMX?

Why bother using HTMX, just use JavaScript!

Here is my navigation template, written in EJS using Bulma CSS framework. It shows a hamburger menu when viewed in a mobile browser. Without JavaScript, it won't expand or collapse the menu.

<nav class="navbar is-dark" role="navigation" aria-label="main navigation">
  <div class="navbar-brand">
    <a class="navbar-item" href="/">
      BRAND
    </a>

    <% if (user) { %>
      <a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="main-menu" id="main-menu-burger">
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
      </a>
    <% } %>
  </div>

  <div class="navbar-menu" id="main-menu">
    <% if (user) { %>
      <div class="navbar-end">
        <div class="navbar-item">
          <div class="buttons">
            <a class="button is-light" hx-post="/logout" hx-swap="innerHTML">
              Log out
            </a>
          </div>
        </div>
      </div>
    <% } %>
  </div>
</nav>

Below is a simple JavaScript to enable toggling the menu.

document.addEventListener("DOMContentLoaded", (event) => {
  // Toggle menu for mobile
  const burger = document.getElementById('main-menu-burger');
  if (burger) {
    burger.addEventListener('click', (e) => {
      const classes = e.target.className.toString().split(' ');
      if (classes.includes('is-active')) {
        htmx.removeClass(htmx.find('#main-menu-burger'), 'is-active');
        htmx.removeClass(htmx.find('#main-menu'), 'is-active');
      } else {
        htmx.addClass(htmx.find('#main-menu-burger'), 'is-active');
        htmx.addClass(htmx.find('#main-menu'), 'is-active');
      }
    });

    // Remove is-active menu on click of any menu item
    const menuItems = document.querySelectorAll('#main-menu .navbar-item a');
    if (menuItems) {
      menuItems.forEach((item) => {
        item.addEventListener('click', () => {
          htmx.removeClass(htmx.find('#main-menu-burger'), 'is-active');
          htmx.removeClass(htmx.find('#main-menu'), 'is-active');
        });
      })
    }
  }
});

It's quite a lot of code. Probably good enough for small applications.

@lysender
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment