Listing Cats
Name | Color | Owner | Category |
---|---|---|---|
Marley | Black | Brian | Real |
Garfield | Orange | Jon | Fictional |
Allows for a shareable URL such as liveviewbasics.com/basic-eight?q=ar .
Documentation:
https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#c:handle_params/3
https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#push_patch/2
NOTE: reference the Setup section for generating the Animals context and adding the Cats to the database used in this example.
scope "/", LiveViewBasicsWeb do
pipe_through :browser
live "/cats", CatLive.Index, :index
end
defmodule LiveViewBasicsWeb.CatLive.Index do
use LiveViewBasicsWeb, :live_view
alias LiveViewBasics.Animals
def mount(_params, _session, socket) do
{:ok, socket}
end
def handle_params(params, _uri, socket) do
socket =
socket
|> stream(:cats, Animals.filter_cats(params), reset: true)
|> assign(:form, to_form(params))
{:noreply, socket}
end
def render(assigns) do
~H"""
<Layouts.app flash={@flash}>
<.header>
Listing Cats
</.header>
<div class="mb-2">
<.form
class="sm:flex justify-left gap-4 items-center"
for={@form}
id="filter-form"
phx-change="filter"
phx-submit="filter"
>
<.input field={@form[:q]} placeholder="Search..." autocomplete="off" phx-debounce="500" />
<.link class="mb-2" patch={~p"/cats"}>
Reset
</.link>
</.form>
<.table id="cats" rows={@streams.cats}>
<:col :let={{_id, cat}} label="Name">{cat.name}</:col>
<:col :let={{_id, cat}} label="Color">{cat.color}</:col>
<:col :let={{_id, cat}} label="Owner">{cat.owner}</:col>
<:col :let={{_id, cat}} label="Category">{cat.category}</:col>
</.table>
</div>
<Layouts.app flash={@flash}>
"""
end
def handle_event("filter", params, socket) do
params =
params
|> Map.take(~w(q))
|> Map.reject(fn {_, v} -> v == "" end)
socket = push_patch(socket, to: ~p"/cats?#{params}")
{:noreply, socket}
end
end
def filter_cats(filter) do
Cat
|> where([c], ilike(c.name, ^"%#{filter["q"]}%"))
|> Repo.all()
end