Skip to content
Advertisement

Updating tailwindCSS class attributes on button click

I’m working on a project that uses pre-made TailwindUI component code. If you refer to this gif, you can see that the code on the site is responsive to mobile design and the hamburger menu toggles on button click.

However, the code given for this does not include the necessary JS, so the toggling of the hamburger menu does not work. I am trying to fix this, this is what i’ve done so far:

  1. I’ve wrapped the flyout menu code in a div and gave it an id ‘mobile-menu’ and a state of ‘hidden’. Inside this menu is the X button, which i gave an id ‘menu-toggle’ since i want this button and the hamburger button to toggle the flyout menu. Below is not the whole code but just the relevant parts
        <div class="absolute z-30 top-0 inset-x-0 p-2 transition transform origin-top-right md:hidden">
          <div class="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 bg-white divide-y-2 divide-gray-50">
            <div class="pt-5 pb-6 px-5">
              <div class="flex items-center justify-between">
                <div>
                  <img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="Workflow">
                </div>
                <div class="-mr-2">
                  <button id="menu-toggle" onclick="" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
                    <span class="sr-only">Close menu</span>
                    <!-- Heroicon name: outline/x -->
                    <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                    </svg>
                  </button>
                </div>
  1. Outside of this div and elsewhere in the code is the hamburger menu button, which i also gave an id ‘menu-toggle’

     <div class="-mr-2 -my-2 md:hidden">
       <button id="menu-toggle" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" aria-expanded="false">
         <span class="sr-only">Open menu</span>
         <!-- Heroicon name: outline/menu -->
         <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
           <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
         </svg>
       </button>
     </div>
    
  2. Finally i’ve added a script tag to the whole .html file (the file does not contain HTML boilerplate because it is a ‘partial’ in a Hugo project, similar to a component in React) and that looks like this:

<script>
  let menuButton = document.getElementById('menu-toggle');
  menuButton.addEventListener('click', function () {
    let flyout = document.getElementById('mobile-menu').classList
    flyout.toggle('hidden')
    flyout.toggle('block')
  })
</script>

but this JS doesn’t work at all. Looking for insight on how to pull this off properly. Thank you!!

Advertisement

Answer

I have written a little code to do the work around. Perhaps it is not the effect you want for your final result, but it is a start. The aproach here is that you can’t apply a toggle function for the same button and the same element toggling diferent class, without use some css at least. Besides, there are so many code errors to explain one by one. Here I let you the code that allows to you open with burger button and close with cross button.

If you need to toggle with the same button just use the menuButtonBurger event and add flyout.classlist.toggle('visible), and remove menuButtonCross. Combined with the css I wrote you this must work.

let menuButtonBurger = document.getElementById('menu-toggle-burger');
let menuButtonCross = document.getElementById('menu-toggle-cross');
menuButtonBurger.addEventListener('click', function () {
    let flyout = document.getElementById('mobile-menu');
    flyout.classList.add('visible');
});
 
menuButtonCross.addEventListener('click', function () {
    let flyout = document.getElementById('mobile-menu');
    flyout.classList.remove('visible');
});
#mobile-menu {
  display: none;
}

#mobile-menu.visible {
  display: block;
}
 <div class="mr-2 my-2 d-md-hidden">
   <button id="menu-toggle-burger" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" aria-expanded="false">
     <span class="sr-only">Open menu</span>
     <!-- Heroicon name: outline/menu -->
     <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
       <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
     </svg>
   </button>
 </div>


<div id="mobile-menu"class="absolute z-30 top-0 inset-x-0 p-2 transition transform origin-top-right d-hidden">
    <div class="rounded-lg shadow-lg ring-1 ring-black ring-opacity-5 bg-white divide-y-2 divide-gray-50">
        <div class="pt-5 pb-6 px-5">
            <div class="flex items-center justify-between">
                <div>
                    <img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-mark-indigo-600.svg" alt="Workflow">
                </div>
                <div class="-mr-2">
                    <button id="menu-toggle-cross" onclick="" type="button" class="bg-white rounded-md p-2 inline-flex items-center justify-center text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500">
                        <span class="sr-only">Close menu</span>
                        <!-- Heroicon name: outline/x -->
                        <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                       </svg>
                  </button>
                </div>
            </div>
        </div>
    </div>
</div>
Advertisement