But in my heex template file in my live view it is expanded by default, instead of hidden. Why? In a non live view heex template file it works as expected.
Any idea why LiveView expands it by default on entering the page?
If this problem couldn’t be solved, could you suggest an alternative to Alpine.js that works with the latest Phoenix 1.6 LiveView?
I use similar code in a project, with Phoenix 1.6 and Heex templates, no issues. It’s probably something else. You don’t have errors in the browser console (or the server) ?
No errors. It works with get request using a standard controller but not with live in router. The code is the same, but for some reason the button’s open is in true state or something when the page loads. It is expanded on the page reload. Unlike the non liveview page in my website. It is the same project, just a different route, so
get "/", PageController, :index
live "/subpage", SubpageLive
I mean it works and I can toggle it in the live view page as well. But the initial state is true instead of false - at least I think it is. And the code is identical. I have tried different buttons and content and it’s the same. Always expanded at default.
The thing is, for Alpine et LiveView to work properly together, you need to plug Alpine into the LiveSocket like this:
import Alpine from "alpinejs";
window.Alpine = Alpine;
Alpine.start();
let liveSocket = new LiveSocket("/live", Socket, {
dom: {
onBeforeElUpdated(from, to) {
if (from._x_dataStack) { window.Alpine.clone(from, to) }
}
}
})
It might be that once the Livesocket connects, and sends back the result, it overrides Alpine applied styles (display: none; in this case), and since Alpine isn’t aware of it, it can’t stop it from happening.
I tried to remove defer from it but without any change.
In fact, now it says in the browser console this:
cdn.min.js:5 Alpine Warning: Unable to initialize. Trying to load Alpine before <body> is available. Did you forget to add defer in Alpine’s <script> tag?
How do you load Alpine in your project? In the root.html.heex (before the </head> tag) as well, like me?
You can just download the latest tag of Alpine then (not sure which file you’ll need, i don’t do it like this), and put that file next to your app.js in order to import it.
Edit: yes, you can do like for topbar
For people who will encounter similar problem your app.js should look something like this:
Also, don’t forget to download the alpine.js file and save it in assets/vendor/ folder as alpine.js or something like that.
import topbar from "../vendor/topbar";
import Alpine from "../vendor/alpine";
// Alpine
window.Alpine = Alpine;
Alpine.start();
let csrfToken = document
.querySelector("meta[name='csrf-token']")
.getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
dom: {
onBeforeElUpdated(from, to) {
if (from._x_dataStack) {
window.Alpine.clone(from, to);
}
},
},
});