Understanding basic use of LiveView.JS module

I came across the LiveView.JS module as I was looking if I can avoid the custom javascript for doing something as simple as class toggle (Toggle classes with Phoenix.LiveView.JS - #13 by trisolaran)

However, when I went to try out the most basic use of toggle explained here, I got stuck getting an unexpected event.

<div>
  <button phx-click={JS.toggle(to: "#togglable")}>✖</button>
  <p id="togglable">"TEST"</p>
</div>

clicking on the button results in the following event

[debug] HANDLE EVENT
  View: PageLive
  Event: "[[\"toggle\",{\"display\":null,\"ins\":[[],[],[]],\"outs\":[[],[],[]],\"time\":200,\"to\":\"#togglable\"}]]"
  Parameters: %{"value" => ""}

As explained later in the blog post, this event was not supposed to come to my LiveView, rather it was supposed to be caught by javascript and call JS.execute() on it.

Looking at liveSocket.connect(), it does contain the bindClick() as the blog post suggests, however I am not sure whether it propagates to JS.execute()

Has any of you faced any similar issues until now?

Quick clarification: JS.toggle doesn’t toggle a class on an element, it toggles its visibility by modifying its display property.

Your code looks good and should just work™

This looks like the string in the phx-click attribute is not being interpreted by LV as a JS command, but it’s instead being used as the name of the event to send to the server, as if you had written: phx-click="event_name".
Never came across this before. Could you maybe share your app.js?

Thank you for pointing it out. I used it as a simple example to understand how LiveView.JS works and could be used in general.

Sure, here it is:

import "phoenix_html"

// Establish Phoenix Socket and LiveView configuration.
import { Socket } from "phoenix"
import { LiveSocket } from "phoenix_live_view"
import topbar from "../vendor/topbar"

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken } })

// Show progress bar on live navigation and form submits
topbar.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" })
window.addEventListener("phx:page-loading-start", info => topbar.show())
window.addEventListener("phx:page-loading-stop", info => topbar.hide())

liveSocket.connect()

window.liveSocket = liveSocket

Thanks. Nothing suspicious in here AFAICS. If you can create a repository with a minimal application that reproduces the issue, I’d be happy to take a look.

1 Like