Calling `show_modal` JS function from LiveView `handle_event`

Hi,

I was wondering if it’s possible to call a JS function (show_modal from core_components.ex in this case) from a handle_event function.

Let’s say I have this socket event handler called to set item_to_edit:

  def handle_event("edit", %{"id" => id}, socket) do
    item = Items.get_item!(id)
    {:noreply, assign(socket, :item_to_edit, item)}
  end

I’d like to open a modal that contains the item form.

Currently I can call open_modal directly in the HEEX template with phx-click, but it would open the modal before the item is loaded, showing blank, and suddenly shows everthing - I figure the UX will probably be worse with slow connections. Ideally I’d like to open the modal after the assign is set.

Is this possible?

Thanks!

Hi, @byw ! :wave:

Looks like what you want it to push_event/3 from the server, catch it in the client with a hook or just event listener and execute JS command with liveSocket.execJS.

See more in details in the section “Handling server-pushed events”

2 Likes

The default phx.gen.live generates something like this:

<.modal
  :if={@live_action in [:new, :edit]}
  id="myclass-modal"
  show
  on_cancel={JS.patch(~p"...")}
>
  <.live_component
   ...
  />
</.modal>

I guess it should work if in the aforementioned :if condition you set the assign variable (in the above example being @live_action) and the corresponding value (in the above example being :new, :edit) to what you desire. I believe that this will delay the displaying of the modal until the assign has the proper value.
I have not tested this solution, though.

2 Likes

Ah, I was creating a live view from scratch. The generator seems to produce a lot of idiomatic code for me, looks great for learning. Thanks!

1 Like