defmodule PhoenixSelect2 do @moduledoc false @missing_function_error_message """ You need give the function to performs the search on live component. <%= live_component SelectWeb.MultiSelectSearchComponent, ..., search_function: your_nice_function %> """ use Phoenix.LiveComponent def render(assigns) do ~L"""
<%= for selected_option <- @selected_options do %> <% end %> <%= for option <- @selected_options do %> <% end %>
""" end def mount(socket) do {:ok, socket |> assign(:search, "") |> assign(:options, []) |> assign(:selected_options, []) |> assign(:empty_message, Map.get(socket, :empty_message, "Without items")) |> assign(:content_key, Map.get(socket, :content_key, :value)) |> assign(:integer_id, Map.get(socket, :integer_id, false)) |> assign(:form, Map.get(socket, :form, %{name: "multi_select"})) |> assign(:field, Map.get(socket, :field, "ids"))} end def handle_event("select-item", %{"option-id" => option_id}, socket) do integer_id = socket.assigns.integer_id clicked_option = if integer_id do socket.assigns.options |> Enum.find(&(&1.id == String.to_integer(option_id))) else socket.assigns.options |> Enum.find(&(&1.id == option_id)) end {:noreply, socket |> update(:selected_options, &(&1 ++ [clicked_option]))} end def handle_event("unselect-option", %{"option-id" => option_id}, socket) do integer_id = socket.assigns.integer_id clicked_option_index = if integer_id do socket.assigns.selected_options |> Enum.find_index(&(&1.id == String.to_integer(option_id))) else socket.assigns.selected_options |> Enum.find_index(&(&1.id == option_id)) end {:noreply, socket |> update(:selected_options, &List.delete_at(&1, clicked_option_index))} end def handle_event("search", %{"value" => text_input}, socket) do search_function = socket.assigns.search_function if is_nil(search_function) do raise(RuntimeError.exception(@missing_function_error_message)) end result = search_function.(text_input) {:noreply, assign(socket, :options, result)} end end