Skip to content

Instantly share code, notes, and snippets.

@edisonywh
Created April 2, 2021 14:53
Show Gist options
  • Save edisonywh/9b06396cdb7db2fe9651af72d6099080 to your computer and use it in GitHub Desktop.
Save edisonywh/9b06396cdb7db2fe9651af72d6099080 to your computer and use it in GitHub Desktop.
Suggestion Component (For use with Backoffice)
defmodule SlickWeb.NewsletterSuggestionComponent do
use SlickWeb, :live_component
def mount(socket) do
socket =
socket
|> assign(:suggestions, [])
|> assign(:picked, nil)
{:ok, socket}
end
def render(assigns) do
~L"""
<input type="text" value="<%= @picked || @value %>" phx-debounce="500" phx-target="<%= @myself %>" phx-keyup="suggest" class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md transition">
<%= if @suggestions != [] do %>
<div class="relative">
<div class="absolute left-0 right-0 rounded-md border border-gray-50 shadow-lg py-2 bg-white">
<%= for {id, name} <- @suggestions do %>
<div
phx-target="<%= @myself %>"
phx-click="pick"
phx-value-id="<%= id %>"
phx-value-name ="<%= name %>"
class="cursor-pointer p-2 hover:bg-gray-200 focus:bg-gray-200">
<%= name %>
</div>
<% end %>
</div>
</div>
<% end %>
"""
end
def handle_event("suggest", %{"value" => ""}, socket) do
socket = socket |> assign(:suggestions, [])
send(self(), {:pick, {:newsletter_id, value: nil}})
{:noreply, socket}
end
def handle_event("suggest", %{"value" => value}, socket) do
require Ecto.Query
suggestions =
Slick.Discovery.list_newsletters(query: value)
|> Ecto.Query.limit(4)
|> Ecto.Query.select([:id, :name])
|> Slick.Repo.all()
|> Enum.map(&{&1.id, &1.name})
socket = socket |> assign(:suggestions, suggestions)
{:noreply, socket}
end
def handle_event("pick", %{"id" => id, "name" => name}, socket) do
socket =
socket
|> assign(:picked, name)
|> assign(:suggestions, [])
send(self(), {:pick, {:newsletter_id, value: id}})
{:noreply, socket}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment