defmodule LiveAdmin.Components.Container.Form.SearchSelect do
use Phoenix.LiveComponent
use Phoenix.HTML
import LiveAdmin, only: [record_label: 2, trans: 1]
alias Phoenix.LiveView.JS
alias LiveAdmin.Resource
@impl true
def update(assigns = %{form: form, field: field}, socket) do
socket =
socket
|> assign(assigns)
|> assign(options: [])
|> assign_selected_option(input_value(form, field))
{:ok, socket}
end
@impl true
def render(assigns = %{disabled: true}) do
~H"""
<%= if @selected_option do %>
<%= record_label(@selected_option, @resource) %>
<% else %>
<%= trans("None") %>
<% end %>
"""
end
@impl true
def render(assigns) do
~H"""
<%= hidden_input(@form, @field,
disabled: @disabled,
value: if(@selected_option, do: @selected_option.id)
) %>
<%= if @selected_option do %>
<%= record_label(@selected_option, @resource) %>
<% else %>
<% end %>
"""
end
@impl true
def handle_event(
"load_options",
%{"value" => q},
socket = %{assigns: %{resource: resource, session: session}}
) do
options =
resource
|> Resource.list([search: q, prefix: socket.assigns.prefix], session, socket.assigns.repo)
|> elem(0)
{:noreply, assign(socket, :options, options)}
end
def handle_event("select", %{"id" => id}, socket) do
socket =
socket
|> assign_selected_option(id)
|> push_event("change", %{})
{:noreply, socket}
end
defp assign_selected_option(socket, id) when id in [nil, ""],
do: assign(socket, :selected_option, nil)
defp assign_selected_option(
socket = %{assigns: %{selected_option: %{id: selected_option_id}}},
id
)
when selected_option_id == id,
do: socket
defp assign_selected_option(socket, id),
do:
assign(
socket,
:selected_option,
Resource.find!(id, socket.assigns.resource, socket.assigns.prefix, socket.assigns.repo)
)
end