Liveview: navigate with phx-click

How can I create or simulate a link to navigate to another page/liveview? I do not want to create a whole <a> element, but create a click event on a tr - like I would do with JS and onClick=window.location....

My first attempt is this, but obviously doesn’t seem to be the right one:

<tr 
  role="button"
  phx-click={live_redirect "foo", to: Routes.admin_foo_path(@socket, :show, foo) }
>
1 Like

I dunno about the <tr> part, but live_redirect/2 might be what you’re looking for if you’re trying to create a link to another liveview.

EDIT: excuse me, I didn’t read your code carefully. live_redirect/2 returns a link, so it’s not something you would emit as a click event. phx-click="xyz" emits an event to the parent liveview (or to the current liveview if target=@myself is specified) which receives it using an event handler. So you wouldn’t put the live_redirect inside of the phx-click.

If it wasn’t clear: live_redirect/2 does not actually perform a redirect. Rather, it creates a link that can create a redirect when clicked.

I’m not sure how to make a <tr> do the same thing. My gut feeling is to use

<%= live_redirect to: Routes.live_path(@socket, MyLive, dir: :asc), replace: false do %>
  <tr> table stuff</tr>
<% end %>
1 Like

Thank you. Besides your solution (not tried yet) it might also be possible to do it with phx-click={bar} where def bar handles the redirect.

I will try both possibilities.

1 Like

The way that events work is like this: you have phx-click="name_of_event". Then, in your module, you define an event handler like this:

def handle_event("name_of_event", _, socket) do
     all the stuff you want
end

handle_event pattern matches on events, and the string for the first arg will match against the string you defined in phx-click. You don’t define a function called name_of_event. Rather, you define a handle_event clause that pattern matches on the name.

1 Like

@christo-ph To tie it all together, something like this should get you there:

def render(assigns) do
  ~H"""
  <button phx-click="redirect">Redirect</button>
  """
end

def handle_event("redirect", _, socket) do
  {:noreply, push_redirect(socket, to: "/path")}
end

4 Likes

So, a lessons learned is, that around <tr> I cannot wrap a <a> element. At least not directly [1]. So the first solution by @caleb-bb will not work here, but surely on other elements.

The phx-click solution works as follows quite nice:

<tr 
  role="button"
  phx-click="go_to_route"
  phx-value-to={Routes.admin_foo_path(@socket, :show, foo)}
>
def handle_event("go_to_inquiry", %{"to" => to}, socket) do
  {:noreply, push_redirect(socket, to: to)}
end

This is then a server side redirect instead of a client/browser based. I do not know if this has any consequences.

Thank you all @caleb-bb @msimonborg

All other ways via Javascript or HTML/CSS can be found here:
[1] javascript - Wrapping a table row in a element (hyperlink) in HTML5 - Stack Overflow

1 Like