Alpine JS weirdness!

grantsmith

Member
Local time
11:34
Joined
Aug 2, 2020
Messages
15

Hello,

Very new to Alpine JS and it seems great. I am experiencing some weirdness though, when I say weirdness, I fully accept I have an error somewhere, and hence misunderstood how something works 🤪

Below is my header. When I click the Hamburger button, the menu-container gets an additional class of show and the body element gets an additional class of noscroll. So far so good. However, my contact button no longer works, by this I mean, if I click it, it does not load the contact page. Additionally it fires the isOpen event and adds the class noscroll to the body class. This is not the intended outcome.

Body:
  <body class="{{ view:bodyClass }}" x-data="{ isOpen: false }" @click="isOpen = !isOpen" :class="{ 'noscroll': isOpen }">
    {{ partial:global/header }}
    <main class="flow__xl">
      {{ template_content | spaceless}}
    </main>
    {{ partial:global/footer }}
  </body>

Header:
<header class="banner" role="banner">
  <div class="wrapper">
    <nav class="navbar" role="navigation" aria-label="main navigation" x-data="{ isOpen: false }" @click.away="isOpen = false" >
      <a class="brand" href="/" aria-label="Navigate back to Home Page" title="Navigate back to Home Page">
        {{ svg src="the-buck-inn-logo.svg" }}
      </a>

      <div class="header__buttons">
        <button class="button primary book" href="/contact" title="Visit the contact page to make a booking">Book a Room</button>
        <button @click="isOpen = !isOpen" :class="{ 'isOpen': isOpen }" :aria-expanded="isOpen ? 'true' : 'false'" type="button" role="button" class="hamburger" aria-controls="menu-container" aria-haspopup="true" aria-label="toggle main menu visibility">
          <span class="line"></span>
          <span class="line"></span>
          <span class="line"></span>
        </button>
      </div>

      <div class="menu-container" x-show.transition.opacity="isOpen" @keydown.escape.window="isOpen = false" :class="{ 'show': isOpen, 'hidden': !isOpen }">
        <ul id="" class="nav">
          {{ nav:header }}
            <li class="nav__item">
              <a class="nav__link" href="{{ url }}" title="{{ title }}">{{ title }}</a>
            </li>
          {{ /nav:header }}
          <li class="nav__item">
            <a class="nav__link reservation" href="tel:{{ company_details:primary_phone }}" title="Telephone The Buck Inn to make a reservation"><span class="reservation__title">Room Reservations</span><br>{{ company_details:primary_phone }}
            </a>
          </li>
        </ul>
      </div>
    </nav>
  </div>
</header>

Appreciate any advise offered

 

Gummibeer

Astroneer
Moderator
Local time
12:34
Joined
Oct 5, 2019
Messages
1,150
Pronouns
he/him

You have a click listener on your body element!? 🤔😳
And you have two x-data which doesn't seem wanted too!? 🧐

 
Last edited:

grantsmith

Member
Local time
11:34
Joined
Aug 2, 2020
Messages
15

Hmm, ok thanks.

What I am trying to achieve is;

The user clicks the Hamburger button and this adds noscroll to the body class and show to the menu-container. Those classes could be anything, that's not the important part.

So it looks like my approach is all wrong?

 

Gummibeer

Astroneer
Moderator
Local time
12:34
Joined
Oct 5, 2019
Messages
1,150
Pronouns
he/him


This should help you. 😉
The x-data attribute opens an Alpine.JS watched/rendered block (like a component in Vue.JS). The data you define in this attribute is available in all child elements but not outside.

HTML:
<div 
  class="p-8"
  x-data="{ menuIsOpen: false }" 
  :class="{ 'bg-black noscroll': menuIsOpen, 'bg-white scroll': !menuIsOpen }"
>
  <nav
    class="px-4 py-2"
    @click.away="menuIsOpen = false"
    :class="{ 'bg-gray-700 text-white': menuIsOpen, 'bg-gray-200 text-black': !menuIsOpen }"
  >
    <button 
      @click="menuIsOpen = !menuIsOpen"
    >
    menu
    </button>
    <ul 
      class="mt-4 space-y-2"
      :class="{ 'block': menuIsOpen, 'hidden': !menuIsOpen }" 
      x-cloak
    >
      <li>Menu Item 1</li>
      <li>Menu Item 2</li>
      <li>Menu Item 3</li>
      <li>Menu Item 4</li>
      <li>Menu Item 5</li>
    </ul>
  </nav>
</div>

 
Last edited:
Top