Phoenix.HTML button that calls a function

Hello. I would love to make a button in HTML that calls an elixir function when the button is clicked.

Code for button here:

<p><a class="btn btn-secondary" onclick="<%= get_signals_support_count(@signal.id) %>" role="button">Like</a>

It calls the function and it works properly only when the page is loaded, not when the button is clicked. Will be grateful for your help!

Drab, this is the very purpose for it.

2 Likes

Let’s first cover the current behavior, and after that, we can figure out a solution.

When using the following in a template

<%= function %>

it is calling the function and inserting the result into the template. So if your get_signals_support_count returns a value, you should see that value inside the onclick attribute after page load. This is how we populate our templates with dynamic content.

If you want to call the function, you need to somehow expose it through a Phoenix controller action or a channel (or use some third-party library like Drab). But to keep things simple let’s create a function in a Controller and expose it as an action through the router.

defmodule MyApp.SomeController do
  use PaceWeb.Web, :controller
 
  def get_signals_support_count(conn, %{"signal_id" => signal_id}) do
    # do your work
  end
end

And add a route to it in your router

get("/get_signals_support_count/:signal_id", SomeController, :get_signals_support_count)

And then you should be able to add a button or link to that path (get_signals_support_count_path(@conn, signal_id)

In general, whatever happens on a web page need to go through an HTTP request or a WebSocket channel. The former requires a request to be sent to the server (either with page reload or AJAX) and the latter can be done purely through javascript with Phoenix channels.

Does that make sense?

5 Likes

You can use one of the following options:

  1. use ajax - create a backend route and call that route using ajax
  2. use Drab as @OvermindDL1 said
  3. create function inside your your_view.ex or your_layout.ex
1 Like

Hmm, I don’t think it would help, you may run function in a view during rendering a template, but not from the JS event. Am I wrong?

3 Likes

Yes, you’re right. Yoy can use it but without js event assign. From my point of view I’ll choose the first option if you don’t want to change the page.

1 Like

So, there’s no built-in approach?

Would LiveView be considered “built-in”?

1 Like