Vikram Sharma
Vikram Sharma

Reputation: 526

Alpine.js x-show stops working when element is made visible with JS

I have a modal that becomes visible via a JS trigger

<div x-show="modalVisible" x.on:click.away="modalVisible = false" id="modal">
</div>

document.getElementById("modal").setAttribute("style", "display: show;")

The problem I am facing is, if I use JS to make the modal visible x.on:click.away does not make the model hidden.

What am I doing wrong?

Upvotes: 1

Views: 8214

Answers (3)

Wan Ahmad Firas
Wan Ahmad Firas

Reputation: 121

Disclaimer: I'm not by any kind of an expert in JS. Just a noob. So, sorry if I theorize it wrongly.

When you set element.style.display = "block" you're setting the property of modalVisible = false (as opposed to toggling the property like modalVisible = !modalVisible) as in your @click.away expression.

However, you have triggered the Alpine's event listener. Alpine will then continue listening to your @click.away event, and set modalVisible = false every time you click outside of the component.

I've played with this kind of situation on my Codepen (with some console.logs to debug), and it will work if I set @click.away ="modalVisible = !modalVisible" that toggles the state rather than sets the state like @click.away = "modalVisible = false". I write the property as show instead of modalVisible: https://codepen.io/wanahmadfiras/pen/KKNrXOO

Upvotes: 2

Vikram Sharma
Vikram Sharma

Reputation: 526

I found a way to make this work using a custom event instead of removing display: none with custom JS.

let event = new CustomEvent("modal", {
  detail: {
    items: []
  }
});
window.dispatchEvent(event);

In my HTML I added

x-on:modal.window="modalVisible = true"

This works though I still don't know why altering directly with JS does not work.

Upvotes: 0

elvinas
elvinas

Reputation: 584

First of all, there is no such thing as display: show, you'd have to set the initial display you had, so perhaps display: block could work.

AlpineJS has a similar example in their github repository, so I just adapted it a little to fit your needs.

<div id="modal" x-data="{ modalVisible: false }">
  <button @click="modalVisible = true">Open Modal</button>

  <ul x-show="modalVisible" @click.away="modalVisible = false">
    Modal Content
  </ul>
</div>

Upvotes: 0

Related Questions