Skip to content

phx-auto-recover doesn't work when all the individual inputs have their own phx-change #4086

@krishandley

Description

@krishandley

Environment

  • Elixir version (please paste the output of elixir -v):
Erlang/OTP 27 [erts-15.2.7] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Elixir 1.18.3 (compiled with Erlang/OTP 27)
  • Operating system
  • MacOS
  • Browsers
Safari 18.6
Chrome 143.0.7499.110 (Official Build) (arm64)

Behavior

phx-auto-recover doesn't work when all the individual inputs have their own phx-change

1st input: Type 1
2nd input: Type 2
3rd input: Type 3
4th input: Type 4
Click button to trigger error/re-connect.

3 and 4 will not be recovered.


Or if you do this.

2nd input: Type 2
Click button to trigger error/re-connect.

2 is receovered, so having a mix of inputs with and without
phx-change seems fine. But all inputs with phx-change seems
to make the form unrecoverable.


If you uncomment the hidden input then the form recovery works fine.

So you can add a hidden input as a workaround. Which I'm fine with now I know.

But thought I'd let you know anyway just in case you wanted to take a look.

Mix.install([
  {:phoenix_playground, "~> 0.1.8"}
])

defmodule DemoLive do
  use Phoenix.LiveView

  def mount(_params, _session, socket) do
    {:ok, assign(socket, v1: nil, v2: nil, v3: nil, v4: nil)}
  end

  def render(assigns) do
    ~H"""
    <div>
      <div>{@v1} {@v2} {@v3} {@v4}</div>

      <form id="f1" phx-change="CHANGE" phx-auto-recover="CHANGE" />
      <input form="f1" name="v1" value={@v1} />
      <input form="f1" name="v2" value={@v2} phx-change="CHANGE" />

      <form id="f2" phx-change="CHANGE" phx-auto-recover="CHANGE" />
      <input form="f2" name="v3" value={@v3} phx-change="CHANGE" />
      <input form="f2" name="v4" value={@v4} phx-change="CHANGE" />
      <%!-- <input form="f2" type="hidden" name="hidden" value="fake" /> --%>

      <button type="button" phx-click="ERR">Trigger Re-connect with error</button>
    </div>
    """
  end

  @impl true
  def handle_event("CHANGE", %{"v1" => v1, "v2" => v2}, socket) do
    {:noreply, assign(socket, v1: v1, v2: v2)}
  end

  @impl true
  def handle_event("CHANGE", %{"v3" => v3, "v4" => v4}, socket) do
    {:noreply, assign(socket, v3: v3, v4: v4)}
  end

  @impl true
  def handle_event("CHANGE", %{"v1" => v1}, socket) do
    {:noreply, assign(socket, v1: v1)}
  end

  @impl true
  def handle_event("CHANGE", %{"v2" => v2}, socket) do
    {:noreply, assign(socket, v2: v2)}
  end

  @impl true
  def handle_event("CHANGE", %{"v3" => v3}, socket) do
    {:noreply, assign(socket, v3: v3)}
  end

  @impl true
  def handle_event("CHANGE", %{"v4" => v4}, socket) do
    {:noreply, assign(socket, v4: v4)}
  end
end

PhoenixPlayground.start(live: DemoLive)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions