Hi everyone,
I’m trying to display a dropdown menu using LiveView and AlpineJS. For the most part, things have worked well, but I’m encountering an issue with this dropdown implementation.
When I try to open and close the dropdown using AlpineJS, the variable is updated (as seen by a console.log
statement), but the dropdown does not get displayed. For some reason, the x-show
value change isn’t being registered for this case.
However, when I comment out the line: liveSocket.connect()
in my app.js
, then it works just as expected. Somehow AlpineJS and LiveView aren’t getting along, and I’d really appreciate any help in resolving this.
I’ve provided the relevant code below:
live/navbar_component.html.heex
<div x-data="{openSettingsDropdown: false}">
<button
type="button"
id="user-menu-button"
:aria-expanded="openSettingsDropdown"
aria-haspopup="true"
x-on:click="openSettingsDropdown = !openSettingsDropdown; console.log(openSettingsDropdown);"
>
</button>
<div
x-cloak
x-show="openSettingsDropdown"
role="menu"
aria-orientation="vertical"
aria-labelledby="user-menu-button"
tabindex="-1"
>
<a
href="#"
class="block px-4 py-2 text-sm text-gray-700"
role="menuitem"
tabindex="-1"
id="user-menu-item-0"
>
Your Profile
</a>
</div>
app.js
import "phoenix_html";
// Establish Phoenix Socket and LiveView configuration.
import { Socket } from "phoenix";
import { LiveSocket } from "phoenix_live_view";
import Alpine from "alpinejs";
window.Alpine = Alpine;
Alpine.start();
let csrfToken = document
.querySelector("meta[name='csrf-token']")
.getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, {
dom: {
onBeforeElUpdated(from, to) {
if (from.__x) {
window.Alpine.clone(from.__x, to);
}
},
},
params: { _csrf_token: csrfToken },
});
liveSocket.connect();
// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000) // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket;
});