I am trying to make a “guess the number” game. I thought I’ll use a form with phx_change
and text_input
. I want to clear the input when the guess is correct. I ended up with this piece of code:
defmodule LiveViewDemoWeb.TestLive do
use Phoenix.LiveView
import Phoenix.HTML.Form
defmodule PlayerInput do
defstruct [:guessed_number]
end
def render(assigns) do
~L"""
<%= f = form_for @changeset, "#", [phx_change: "guess"] %>
<%= text_input f, :guessed_number %>
</form>
"""
end
def mount(_session, socket) do
socket =
socket
|> assign(%{changeset: player_input_changeset(%{guessed_number: 9})})
{:ok, socket}
end
def handle_event("guess", %{"player_input" => %{"guessed_number" => ""}}, socket) do
{:noreply, socket}
end
def handle_event("guess", %{"player_input" => player_input}, socket) do
changeset =
player_input
|> player_input_changeset()
case changeset.changes.guessed_number do
10 ->
{:noreply,
assign(
socket,
%{changeset: player_input_changeset(%{})}
)}
_ ->
{:noreply,
assign(
socket,
%{changeset: changeset}
)}
end
end
defp player_input_changeset(params) do
types = %{guessed_number: :integer}
{%PlayerInput{}, types}
|> Ecto.Changeset.cast(params, Map.keys(types))
end
end
I can set the initial value in the form by assigning the changeset in mount
function. But if I try to do the same in handle_event("guess", ...
, it doesn’t reset the field. Even if I put some value there, it is ignored. Am I doing something wrong or is it a known limitation that I can’t change form values inside phx-change
event?