phoenix_live_view icon indicating copy to clipboard operation
phoenix_live_view copied to clipboard

_target is [undefined] when using JS API for phx-change events in combination with select tags

Open Menkir opened this issue 2 years ago • 0 comments

Environment

  • Elixir version (elixir -v): 1.12
  • Phoenix version (mix deps): 1.6.11
  • Phoenix LiveView version (mix deps): 17.5
  • Operating system: ubuntu jammy
  • Browsers you attempted to reproduce this bug on (the more the merrier): Chrome 100.0.4896.60
  • Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: yes

Actual behavior

Actually i use Surface but the problem happens on live view side:

I wan't to create a Form that uses the JS API to dispatch onChange events. My event handler want's to match on the _target key in the parameters but it crashes because the target seems to be undefined.

Consider the following example:

defmodule SelectBugWeb.Components.Form do
  use Phoenix.LiveComponent
  import Phoenix.HTML.Form
  alias Phoenix.LiveView.JS
  def render(assigns) do
    ~H"""
    <div>
      <.form let={f} for={:new_user} phx-change={JS.push("form-change", target: @myself)}>
        <%= label f, :username %>
        <%= text_input f, :username %>

        <%= label f, :email %>
        <%= text_input f, :email %>

        <%= select f, :group, ["Foo": :foo, "Baz": :baz, "Bar": :bar] %>

        <%= submit "Save" %>
      </.form>
    </div>
    """
  end

  def handle_event("form-change", %{"_target" => ["new_user", key]}, socket) 
    when key in ~w(username email group)
  do
    # do some change :D
    {:noreply, socket}
  end
end

The text_input tags are emitting the correct target while the select tag not. Instead the select tag send's ['undefined'] .

I inspected the part of the change handler in the debugger https://github.com/phoenixframework/phoenix_live_view/blame/v0.17.5/assets/js/phoenix_live_view/js.js#L40

For input tags it will always work because it will be checked against it instance type. But for selects it expects a _target key which is not provided by the JS API.

Menkir avatar Aug 22 '22 13:08 Menkir