Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select element is reset to the default value after changing it and running server validation on the container form #3107

Open
eldano opened this issue Feb 10, 2024 · 2 comments · May be fixed by #3127

Comments

@eldano
Copy link
Contributor

eldano commented Feb 10, 2024

Environment

  • Elixir version (elixir -v): 1.16.0
  • Phoenix version (mix deps): 1.7.10
  • Phoenix LiveView version (mix deps): 0.20.4 and 0.20.5
  • Operating system: MacOS 14.2.1
  • Browsers you attempted to reproduce this bug on (the more the merrier): Chrome 121.0.6167.85. Firefox
  • Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: Yes

Actual behavior

I have a liveview with a form with a phx-change="validate" that just enables the submit button.
Inside the form I have a select that is not currently doing anything, it has two options.
When I select the second option, the validate event changes an assign that enables my submit button, but the select goes back to the default option after a subtle flicker.
If I don't change any assigns in the validate event, then everything works as expected.
Probably is similar to the issue report #3083 but this scenario seems a bit simpler.

Application.put_env(:sample, Example.Endpoint,
  http: [ip: {127, 0, 0, 1}, port: 5001],
  server: true,
  live_view: [signing_salt: "aaaaaaaa"],
  secret_key_base: String.duplicate("a", 64)
)

Mix.install([
  {:plug_cowboy, "~> 2.5"},
  {:jason, "~> 1.0"},
  {:phoenix, "1.7.10"},
  {:phoenix_live_view, "0.20.4"}
])

defmodule Example.ErrorView do
  def render(template, _), do: Phoenix.Controller.status_message_from_template(template)
end

defmodule Example.HomeLive do
  use Phoenix.LiveView, layout: {__MODULE__, :live}

  def mount(_params, _session, socket) do
    {:ok,
      socket
      |> assign(:form, Phoenix.Component.to_form(%{}))
      |> assign(:disabled, true)
    }
  end

  def handle_event("validate", _, socket) do
    {:noreply, assign(socket, :disabled, false)}
  end

  def render("live.html", assigns) do
    ~H"""
    <script src={"https://cdn.jsdelivr.net/npm/phoenix@1.7.10/priv/static/phoenix.min.js"}></script>
    <script src={"https://cdn.jsdelivr.net/npm/phoenix_live_view@0.20.4/priv/static/phoenix_live_view.min.js"}></script>
    <script>
      let liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket)
      liveSocket.connect()
    </script>
    <style>
      * { font-size: 1.1em; }
    </style>
    <%= @inner_content %>
    """
  end

  def render(assigns) do
    ~H"""
    <.form for={@form} phx-change="validate" style="display: flex;">
      <select>
        <option value="ONE">ONE</option>
        <option value="TWO">TWO</option>
      </select>

      <button disabled={@disabled}>OK</button>
    </.form>
    """
  end
end

defmodule Example.Router do
  use Phoenix.Router
  import Phoenix.LiveView.Router

  pipeline :browser do
    plug(:accepts, ["html"])
  end

  scope "/", Example do
    pipe_through(:browser)

    live("/", HomeLive, :index)
  end
end

defmodule Example.Endpoint do
  use Phoenix.Endpoint, otp_app: :sample
  socket("/live", Phoenix.LiveView.Socket)
  plug(Example.Router)
end

{:ok, _} = Supervisor.start_link([Example.Endpoint], strategy: :one_for_one)
Process.sleep(:infinity)

Expected behavior

The select isn't changed on re-render as only the assign that enables the button is changed.
This worked fine in 0.20.1, 0.20.2 and 0.20.3. It got broken in 0.20.4 and is still broken in 0.20.5 and master

@ityonemo
Copy link
Contributor

I am observing the same issue.

SteffenDE added a commit to SteffenDE/phoenix_live_view that referenced this issue Feb 17, 2024
@SteffenDE SteffenDE linked a pull request Feb 17, 2024 that will close this issue
@eldano
Copy link
Contributor Author

eldano commented Apr 2, 2024

A workaround for this issue is adding the html attribute "selected" to the first option (or the one that should be selected by default)
This is probably why not more people are seeing this issue, because that is covered by the component <.input type="select"...

I still think it's a valid issue though

SteffenDE added a commit to SteffenDE/phoenix_live_view that referenced this issue May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants