zoedsoupe
While searching and studying about live view I found this page of LiveComponent documentation, and reading more carefully about the “cost of a live component”, here: Phoenix.LiveComponent — Phoenix LiveView v1.2.5
Then it gives a not to do example, using a LiveComponent to wrap DOM events, like:
defmodule MyButton do
use Phoenix.LiveComponent
def render(assigns) do
~H"""
<button class="css-framework-class" phx-click="click">
<%= @text %>
</button>
"""
end
def handle_event("click", _, socket) do
_ = socket.assigns.on_click.()
{:noreply, socket}
end
end
So it preferable to use a functional component! Then, it was I did! I have this function component to wrap and style the native DOM button tag:
attr :style, :string, values: ~w(primary secondary), required: true
attr :submit, :boolean, default: false
attr :icon, :atom, required: false, default: nil
attr :class, :string, default: ""
attr :rest, :global, doc: ~s(used for phoenix events like "phx-click" and "phx-target")
slot :inner_block
def button(assigns) do
~H"""
<button
type={if @submit, do: "submit", else: "button"}
class={["btn", "btn-#{@style}", @class]}
{@rest}
>
<.icon :if={@icon} name={@icon} />
<.text :if={@style == "primary"} size="base" color="text-white-100">
<%= render_slot(@inner_block) %>
</.text>
<.text :if={@style != "primary"} size="base" color="text-blue-80">
<%= render_slot(@inner_block) %>
</.text>
</button>
"""
end
To be reusable in any phoenix template with a predefined style. My question is, how this function component can handle events, in this case, phx-click?
I used the button like this: https://github.com/peapescarte/pescarte-plataforma/blob/main/lib/pescarte_web/templates/landing_html/show.html.heex#L56-L58
However no event is trigged as can be seen in this little video:
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
benwilson512
In short, it can’t. In order for a component to receive events it needs to be a stateful component that does
use Phoenix.LiveComponentin its own module.You generally also need to
phx-target={@myself}to ensure that the events go to your component.cmo
Function components do not handle events. Handle them in the parent liveview or livecomponent.
On a side note, this could be shorter:
Could be:
zoedsoupe
so the template needs to be a
live viewand not a rawhtmltemplate, right? Ok, this explain a lot! I’ll try to do this!Oh, thanks for this little tip, I implement so fast I didn’t noticed haha. Actually I really would like to se a
:elseand:if-elsedirective likevuein the future, although it’s not mandatoryzoedsoupe
HEEx templates can be both live view or not, depending the usage of the screen! Ok, I need to practice more this concept
zoedsoupe
but phx-target only works inside a live view template, right? then for a button component phx-target to
@myselfdoesn’t make much sense as it need to handle dozens of different events in different screens, not related.I now see the problem is I’m trying to handle an event on a “raw” html (heex) template and not a live view
benwilson512
I don’t really understand what this means. A functional component used by a root live view is still “in live view”. If you have a
phx-clickon a functional component then the event will simply go to the live view itself. There is no such thing as having ahandle_eventwithout live view at all, what would even be handling the event?zoedsoupe
I mean: for a new phoenix project we have:
simplified. Then, those
landing_html.exfiles aren’t live views, are templates that can use components, but they do not handle events, right?Example, here’s my
login_html.exfile:This is not a live view, so cannot handle event and therefore does not define
@myself. Am I wrong? To define a live view I need touse Phoenix.LiveViewthen implementmount/3andhandle_event/3benwilson512
Hey @zoedsoupe you’re absolutely right, it’s only very recently that Phoenix started using
heexfor controllers and I basically totally forgot it does that now!So back to your question: Yea you can only do
handle_eventandphx-targetstuff on components used in a live view. If you do need to use a functional component between both live and traditional views you could probably pass inmyself: nilas an assign, but also the button won’t really work.zoedsoupe
Thanks for confirming this conception! there’s any part of the official documentation that explain this difference explicitly? I think the most important part is to understand that function components will not work with events on controllers templates.
For now i don’t need a component to trigger events on controller templates, a form action here is to save the session, so it can be safely a submit button to another route.
benwilson512
Not in the way you’re looking for that I see. That said if you read Components and HEEx — Phoenix v1.8.8 and the other docs it links to, you’ll notice that the word
eventnever even appears. It’s only when you get to the live view docs do you start seeingevents andhandle_event.