How to call handle_event with params without using a form?

229 Views Asked by At

How do I call handle_event wish specific params without using a form?

I'd like table row details to be displayed in a modal when row_click happens. I am able to trigger handle events, but params are always %{}.

1

There are 1 best solutions below

0
On

Check out the docs about click events to read more about event parameters and about JS commands.

You can use JS.push to send an event (with params) or use any other of the JS functions.

That was the short answer, now the long answer, hopefully more specific to your second question. If not, you should have provided more details. ;p

Show a modal with table row details

I'm going to assume we just created a new Phoenix project, ran mix phx.gen.live Blog Post posts title:string body:text and followed the instructions to create a new live view. The goal is to click on a table row in the index view and show a modal with the table row details.

In index.html.heex there already is a modal for the new and edit actions. Let's add a modal for the show action right below it:

<.modal :if={@live_action == :show} id="post-show-modal" show on_cancel={JS.patch(~p"/posts")}>
  <h1 class="text-lg font-semibold leading-8 text-zinc-800"><%= @post.title %></h1>
  <p class="mt-2 text-sm leading-6 text-zinc-600"><%= @post.body %></p>
</.modal>

We want this modal to open when a table row is clicked, but right now the row_click function of the table navigates to /posts/#{post} wich is routed to the PostLive.Show view. Let's change that by routing the show route/action to PostLive.Index. In router.ex change the line:

live "/posts/:id", PostLive.Show, :show
# to
live "/posts/:id", PostLive.Index, :show

and add a corresponding action to the PostLive.Index module (post_live/index.ex):

  defp apply_action(socket, :show, %{"id" => id}) do
    socket
    |> assign(:page_title, "Show Post")
    |> assign(:post, Blog.get_post!(id))
  end

Now everything is wired up and when a table row is clicked, the show modal opens.

To improve on this a bit more, change the row_click function of the table to use patch instead of navigate, because we navigate to the same live module (more about that here):

row_click={fn {_id, post} -> JS.patch(~p"/posts/#{post}") end}