Handling Events
Events are a common part of any LiveView application. On the server, LiveView Native handles events identically to LiveView on the web. How the client handles events depends on the native platform and its respective client implementation. This document provides some general information on events regardless of platform.
Translated Bindings
Platforms may translate Phoenix bindings to their native counterparts
where it makes sense. The most common example of this is phx-click
which listens for tap events on SwiftUI and Jetpack
targets.
On the server, events are handled using standard LiveView callbacks like handle_event/3
regardless of what platform they
come from. Callbacks can also be shared across platforms, assuming the events and their params are compatible. Here is a
basic example of sharing a handle_event/3
callback in this way:
# hello_live.ex
defmodule MyAppWeb.HelloLive do
use Phoenix.LiveView
use MyAppWeb, :live_view
@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, name: "World")}
end
@impl true
def render(%{format: :swiftui} = assigns) do
# This UI renders on the iPhone / iPad app
~SWIFTUI"""
<VStack>
<Text phx-click="click_test">Hello <%= @name %>!</Text>
</VStack>
"""
end
@impl true
def render(%{} = assigns) do
# This UI renders on the web
~H"""
<div class="flex w-full h-screen items-center">
<span class="w-full text-center" phx-click="click_test">
Hello <%= @name %>!
</span>
</div>
"""
end
@impl true
def handle_event("click_test", _params, socket) do
# This event can be called from both SwiftUI and the web
{:noreply, assign(socket, name: "José")}
end
end
In this example, clicking the "Hello World" button changes it to say "Hello José" on both the web and iOS.
The same handle_event/3
callback is fired in both cases.
Change Events
In LiveView Native, elements can support client-side changes to their value outside of a <form>
.
Synchronizing the values must be handled manually by the LiveView using change events.
Client-side changes
Use the phx-change
attribute to respond to client-side changes to an element's value.
<TextField text={@text} phx-change="value-changed" />
A handle_event/3
implementation with the name "value-changed"
will be called anytime the user changes the text of the TextField
.
def handle_event("value-changed", new_value, socket) do
{:noreply, assign(socket, text: new_value)}
end
The phx-debounce
, phx-throttle
, and phx-target
attributes can be used to configure the event.
Refer to the documentation for an element to find out if it supports client-side changes.
Server-side changes
Each element has an attribute that controls its value.
For example, TextField
in the SwiftUI client uses the attribute text
.
See the documentation for an element to find out what attribute it uses.
Whenever the attribute's value is changed, the client will update to display the new value. No change event is sent when the server updates the value.
Modifier change events
Some modifiers have values that can be changed by the client.
To receive change events on these modifiers, pass a LiveViewNativePlatform.Modifier.Types.Event
to the change
argument.
sheet(is_presented: @show, change: "presentation-changed")
Provide a map to change
for more advanced configuration.
sheet(is_presented: @show, change: %{ event: "presentation-changed", debounce: 2000, target: @myself })
A change event will be sent with every argument of the modifier that can be change-tracked.
def handle_event("presentation-changed", %{ "is_presented" => show }, socket) do
{:noreply, assign(socket, show: show)}
end
In the example above, the server can show/hide the sheet by setting the show
assign.
When the user swipes down on the sheet to close it, the "presentation-changed"
event will be called with the value false
.
See the documentation for a modifier to find out which arguments can be change-tracked.