Liveview click event not triggering

I am trying clone this lib for multi select with search in react using live view, but to do the selection of option the click event (“select-item” event on component below) is not captured nor throw a exception of undefined handle_event function, one thing I tested is that chaging from phx-click to phx-capture-click on li it “works”, but when click out from search bar the click event is called once again.

the component:

defmodule SelectWeb.MultiSelectSearchComponent do
  use Phoenix.LiveComponent
  # import Phoenix.HTML.Form

  def render(assigns) do
    ~L"""
    <div class="react-multi-search-select-container">
      <%= for {selected_option, index} <- @selected_options |> Enum.with_index() do %>
        <button 
          phx-value-selected-index="<%= index %>" 
          class="react-multi-search-select-selected-option"
          phx-click="remove-option"
          phx-click="<%= @myself %>"
        >
          <%= selected_option %>
        </button>
      <% end %>

      <div class="react-multi-search-select-search-wrapper">
        <input
          type="text"
          value="<%= @search %>"
          placeholder="Search"
          autoComplete="off"
          phx-focus="toggle-search"
          phx-blur="toggle-search"
          phx-key-up="search"
          phx-target="<%= @myself %>"
        />
      </div>

      <%= unless @toggled do %>
        <ul class="react-multi-search-select-options-container">
          <%= if @options != [] do %>
            <!-- pode usar aqui uma first class function para substituir o Enum.with_index -->
            <%= for {option, index} <- @options |> Enum.with_index() do %>
              <li 
                phx-click="select-item"
                phx-value-option-index="<%= index %>" 
                phx-target="<%= @myself %>"
              >
                <%= option %>
              </li>
            <% end %>
          <% else %>
            Sem opções
          <% end %>
        </ul>
      <% end %>
    </div>
    """
  end

  def mount(socket) do
    {:ok,
     socket
     |> assign(:toggled, true)
     |> assign(:search, "")
     |> assign(:options, ["banana", "uva"])
     |> assign(:selected_options, ["pera"])}
  end

  def handle_event("toggle-search", _params, socket) do
    toggled = socket.assigns.toggled
    {:noreply, assign(socket, :toggled, !toggled)}
  end

  def handle_event("select-item", %{"option-index" => option_index}, socket) do
    IO.puts "asdfasdfasdf"
    option_index = String.to_integer(option_index)
    options = socket.assigns.options

    {:noreply,
     update(socket, :selected_options, fn selected_options ->
       selected_options ++ [Enum.at(options, option_index)] |> IO.inspect()
     end)}
  end
end

This component is in the default page_live.html.leex, like this: <%= live_component SelectWeb.MultiSelectSearchComponent, id: "select" %>

Why the click phx-click event from <li> is not called?

Can you click an li? Does using an anchor tag work?

<li>
  <a 
      phx-click="select-item"
      phx-value-option-index="<%= index %>" 
      phx-target="<%= @myself %>"
  >
    <%= option %>
  </a>
</li>

let me test here

No, just same thing, I click on it but nothing happing

One strange thing is that if the ul is outside from unless it works, but I lose the behaviour of toggle/untoggle the search result.

    <ul class="react-multi-search-select-options-container">
        <%= if @options != [] do %>
          <!-- pode usar aqui uma first class function para substituir o Enum.with_index -->
          <%= for {option, index} <- @options |> Enum.with_index() do %>
            <li 
              phx-click="select-item"
              phx-value-option-index="<%= index %>" 
              phx-target="<%= @myself %>"
            >
              <%= option %>
            </li>
          <% end %>
        <% else %>
          Sem opções
        <% end %>
      </ul>

If has some way to toggle and untoggle using css/hiden attribute and the @toggled assign will be wonderfull, but the way that I know is like this and not works:

<ul class="react-multi-search-select-options-container" <%= if @toggled, do: "hidden" %>>

The problem was that @toggled when change state close more faster than time to click and trigger the phx-click. The solution is:

  • if is using new version of liveview 0.18.x, use phx-clickaway on root div to toggle
  • in my case I do not use newer version of liveview so I solved this using Alpine and put a delay to hide the element before trigger the phx-click event

See the code here