feat: adds SearchBar Live Component
This commit is contained in:
parent
dd03000428
commit
78588cbad9
3 changed files with 97 additions and 0 deletions
62
lib/mv_web/live/components/search_bar_component.ex
Normal file
62
lib/mv_web/live/components/search_bar_component.ex
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
defmodule MvWeb.Components.SearchBarComponent do
|
||||||
|
@moduledoc """
|
||||||
|
Provides the SearchBar Live-Component.
|
||||||
|
|
||||||
|
- uses the DaisyUI search input field
|
||||||
|
- sends search_changed event to parent live view with a query
|
||||||
|
"""
|
||||||
|
use MvWeb, :live_component
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def update(assigns, socket) do
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> assign_new(:query, fn -> "" end)
|
||||||
|
|> assign_new(:placeholder, fn -> gettext("Search...") end)
|
||||||
|
|
||||||
|
{:ok, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def render(assigns) do
|
||||||
|
~H"""
|
||||||
|
<form phx-change="search"
|
||||||
|
phx-target={@myself}class="flex" role="search" aria-label="Search">
|
||||||
|
<label class="input">
|
||||||
|
<svg
|
||||||
|
class="h-[1em] opacity-50"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<g
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-width="2.5"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<circle cx="11" cy="11" r="8"></circle>
|
||||||
|
<path d="m21 21-4.3-4.3"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
placeholder={@placeholder}
|
||||||
|
value={@query}
|
||||||
|
name="query"
|
||||||
|
phx-debounce="300"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</form>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
# Function to handle the search
|
||||||
|
def handle_event("search", %{"query" => q}, socket) do
|
||||||
|
# Forward a high level message to the parent
|
||||||
|
send(self(), {:search_changed, q})
|
||||||
|
{:noreply, assign(socket, :query, q)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
defmodule MvWeb.MemberLive.Index do
|
defmodule MvWeb.MemberLive.Index do
|
||||||
use MvWeb, :live_view
|
use MvWeb, :live_view
|
||||||
|
import Ash.Expr
|
||||||
|
import Ash.Query
|
||||||
import MvWeb.TableComponents
|
import MvWeb.TableComponents
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
|
|
@ -10,12 +12,38 @@ defmodule MvWeb.MemberLive.Index do
|
||||||
{:ok,
|
{:ok,
|
||||||
socket
|
socket
|
||||||
|> assign(:page_title, gettext("Members"))
|
|> assign(:page_title, gettext("Members"))
|
||||||
|
|> assign(:query, "")
|
||||||
|> assign(:sort_field, :first_name)
|
|> assign(:sort_field, :first_name)
|
||||||
|> assign(:sort_order, :asc)
|
|> assign(:sort_order, :asc)
|
||||||
|> assign(:members, sorted)
|
|> assign(:members, sorted)
|
||||||
|> assign(:selected_members, [])}
|
|> assign(:selected_members, [])}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# Receive messages from any toolbar component
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
|
# Function to handle search
|
||||||
|
@impl true
|
||||||
|
def handle_info({:search_changed, q}, socket) do
|
||||||
|
members =
|
||||||
|
Mv.Membership.Member
|
||||||
|
|> Ash.Query.filter(
|
||||||
|
expr(fragment("search_vector @@ plainto_tsquery('simple', ?)", ^q))
|
||||||
|
)
|
||||||
|
|> Ash.read!()
|
||||||
|
|
||||||
|
IO.inspect(members)
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> assign(:query, q)
|
||||||
|
|> assign(:members, members)}
|
||||||
|
end
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
# Handle Events
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("delete", %{"id" => id}, socket) do
|
def handle_event("delete", %{"id" => id}, socket) do
|
||||||
member = Ash.get!(Mv.Membership.Member, id)
|
member = Ash.get!(Mv.Membership.Member, id)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,13 @@
|
||||||
</:actions>
|
</:actions>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
|
<.live_component
|
||||||
|
module={MvWeb.Components.SearchBarComponent}
|
||||||
|
id="search-bar"
|
||||||
|
query={@query}
|
||||||
|
placeholder={gettext("Search...")}
|
||||||
|
/>
|
||||||
|
|
||||||
<.table
|
<.table
|
||||||
id="members"
|
id="members"
|
||||||
rows={@members}
|
rows={@members}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue