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

Invalid value reported for inputs with name="value" #2680

Closed
jonatanklosko opened this issue Jun 8, 2023 · 6 comments
Closed

Invalid value reported for inputs with name="value" #2680

jonatanklosko opened this issue Jun 8, 2023 · 6 comments

Comments

@jonatanklosko
Copy link
Contributor

When an input has name="value", the value is reported as [object HTMLInputElement].

Phoenix v1.7.3, LV v0.19.1

Reproduction

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

Mix.install([
  {:plug_cowboy, "~> 2.6"},
  {:jason, "~> 1.4"},
  {:phoenix, "1.7.3"},
  {:phoenix_live_view, "0.19.1"}
])

Application.put_env(:nx, :default_backend, EXLA.Backend)

defmodule PhoenixDemo.Layouts do
  use Phoenix.Component

  def render("live.html", assigns) do
    ~H"""
    <script src="https://cdn.jsdelivr.net/npm/phoenix@1.7.3/priv/static/phoenix.min.js">
    </script>
    <script
      src="https://cdn.jsdelivr.net/npm/phoenix_live_view@0.19.1/priv/static/phoenix_live_view.min.js"
    >
    </script>
    <script>
      const liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket);
      liveSocket.connect();
    </script>
    <script src="https://cdn.tailwindcss.com">
    </script>
    <%= @inner_content %>
    """
  end
end

defmodule PhoenixDemo.ErrorView do
  def render(_, _), do: "error"
end

defmodule PhoenixDemo.SampleLive do
  use Phoenix.LiveView, layout: {PhoenixDemo.Layouts, :live}

  @impl true
  def mount(_params, _session, socket) do
    {:ok, assign(socket, text: "")}
  end

  @impl true
  def render(assigns) do
    ~H"""
    <form phx-change="change" phx-submit="submit">
      <input type="text" name="value" value={@text} phx-debounce="blur" />
      <div><%= @text %></div>
    </form>
    """
  end

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

defmodule PhoenixDemo.Router do
  use Phoenix.Router

  import Phoenix.LiveView.Router

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

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

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

defmodule PhoenixDemo.Endpoint do
  use Phoenix.Endpoint, otp_app: :sample

  socket("/live", Phoenix.LiveView.Socket)
  plug(PhoenixDemo.Router)
end

# Application startup

{:ok, _} = Supervisor.start_link([PhoenixDemo.Endpoint], strategy: :one_for_one)

Process.sleep(:infinity)

@jonatanklosko
Copy link
Contributor Author

Regression on v0.18.18 -> v0.19.0.

rktjmp added a commit to rktjmp/phoenix_live_view that referenced this issue Jun 10, 2023
…ramework#2680

`extractMeta` receives a "root element".

When this element is an input, we want to retrieve the current value.

When the element is a form, `form.key` will look up any inputs in the
form with the name "key". If an input has the name "value", then we would
retrieve the input element *as the value*, instead of getting the value
of an input.

We explicitly avoid getting the value of a form to avoid this edgecase.

At time of writing, the value attribute is valid on button, data, input,
li, meter, option, progress and param tags.
@rktjmp
Copy link
Contributor

rktjmp commented Jun 10, 2023

This is caused by serializeForm & extractMeta

Serialise form attaches values it receives as "meta" data:

for(let metaKey in meta){ params.append(metaKey, meta[metaKey]) }

extractMeta grabs the element value key if present.

  • form.key will look in the form for an element named key.
  • When the root el passed to extractMeta is a <form>, el.value is not the value of an input, but the actual input element.
  • so meta.value = form.inputs_by_name["value"] essentially.

@hubertlepicki
Copy link

I'm having the same issue across the app where I have name="value". Going to try the PR above now.

@hubertlepicki
Copy link

hubertlepicki commented Jun 12, 2023

I have updated the app I work on with @rktjmp PR, and rebuilt the assets and can confirm that indeed it resolves the problem of [object HTMLInputElement] appearing inside text inputs throughout my app.

This is not a livebook app, it's just a form app that uses `input name="value"`` across multiple forms and we have seen them all broken with liveview 0.19 update and this indeed fixes it.

To whoever merges this: please do remember to run mix assets.build to regenerate the compiled JavaScript files.

@chrismccord
Copy link
Member

Fixed in 0.19.2

@hubertlepicki
Copy link

@chrismccord I confirm v0.19.2 resolves the issue, thanks!

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

No branches or pull requests

4 participants