Search with Shareable URL

Listing Cats

Reset
NameColorOwnerCategory
Marley Black Brian Real
MJ Tortoiseshell Brian Real
Mr. Business Gray Gayle Fictional
Garfield Orange Jon Fictional
Goose Orange Wendy 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}>
      <h1 class="text-4xl font-bold text-center">Search with Shareable URL</h1>
      <.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>
    """
  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