Can we use Liveview JS commands inside a hook?

Hi

Is it possible to use JS commands inside hooks? For example I want to focus first element in a dialog I am implementing with html dialog element using a hook.

** I can do it without using hooks using JS commands. But let’s assume I want to use a hook here.

The LiveView version – 1.0.0-rc.7 says in the changelog enhancements -

  • Expose programmable JS command interface to hooks for showing, hiding, addClass, etc from a hook which integrates with server DOM patching

Can someone please point me in the right direction, about how to use JS commands inside hooks.

Thank you so much.

1 Like

this.js() gives you an object with function calls mirroring the elixir level ones. The js level docs are sadly best looked up in the source code / the commit having added it.

3 Likes

Thank you so much. You are a real saviour!

We do plan on improving them though! PRs are of course also always welcome :smiley:

1 Like

Does this need to be called somewhere in particular? I’m still on the 1.0 RC for this project but console.log(this.js) in mounted() is undefined.

EDIT: nvm, I can’t read, I’m on the wrong rc version.

Actually, I’m not quite sure how to use this. I’m trying to use this.js().exec although I don’t think actually corresponds to JS.exec? It says it takes encoded JS so I’m assuming I can’t do this.js().exec('phx-click', { to: '#some-element' })?

…I guess I don’t really need this, actually :thinking: Can just use dispatchEvent.

I solved this issue using this.liveSocket.execJS from the hook.

in the LiveView:

~H"""
<div id="foo" phx-highlight={JS.add_class("....")}/>
"""

in the hook

let element = document.getElementById("foo");
this.liveSocket.execJS(
  element,
  element.getAttribute("phx-highlight")
);

On the client there’s no need for LV to prescribe how to figure out what the js command to execute is – it isn’t by itself a js command with a need to be encodeable as one. You can just fetch it however you want and provide it to exec. E.g.

let el = docuement.querySelector("#some-element");
let command = el.getAttribute("phx-click");
this.js().exec(command)

But it could be any other means you might have as well, not even using ids at all, ….

Oh yes, this makes sense. Thanks! I was getting tripped up as the other ones seem to follow the same API as there Elixir counterparts. Didn’t even think about getAttribute.