Cat 2
-
NameMJ
-
ColorTortoiseshell
-
OwnerBrian
-
CategoryReal
NOTE: reference the Setup section for generating the Animals context and adding the Cats to the database used in this example.
NOTE: while you can click the "Edit" link here and the "Edit Cat" button on the show page and interact with the form, editing cats is disabled for this preview. The code below will still edit new cats.
scope "/", LiveViewBasicsWeb do
pipe_through :browser
live "/cats", CatLive.Index, :index
live "/cats/:id", CatLive.Show, :show
live "/cats/:id/edit", CatLive.Form, :edit
end
defmodule LiveViewBasicsWeb.CatLive.Index do
use LiveViewBasicsWeb, :live_view
alias LiveViewBasics.Animals
def mount(_params, _session, socket) do
socket = stream(socket, :cats, Animals.list_cats())
{:ok, socket}
end
def render(assigns) do
~H"""
<Layouts.app flash={@flash}>
<.header>
Listing Cats
</.header>
<div class="mb-2">
<.table
id="cats"
rows={@streams.cats}
row_click={fn {_id, cat} -> JS.navigate(~p"/cats/#{cat}") end}
>
<: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>
<:action :let={{_id, cat}}>
<div class="sr-only">
<.link navigate={~p"/cats/#{cat}"}>Show</.link>
</div>
<.link navigate={~p"/cats/#{cat}/edit"}>Edit</.link>
</:action>
</.table>
</div>
<Layouts.app flash={@flash}>
"""
end
end
defmodule LiveViewBasicsWeb.CatLive.Show do
use LiveViewBasicsWeb, :live_view
alias LiveViewBasics.Animals
def mount(%{"id" => id}, _session, socket) do
socket = assign(socket, :cat, Animals.get_cat!(id))
{:ok, socket}
end
def render(assigns) do
~H"""
<Layouts.app flash={@flash}>
<.header>
Cat {@cat.id}
<:actions>
<.button navigate={~p"/cats/#{@cat}/edit"}>
<.icon name="hero-pencil-square" /> Edit Cat
</.button>
</:actions>
</.header>
<div class="mb-2">
<.list>
<:item title="Name">{@cat.name}</:item>
<:item title="Color">{@cat.color}</:item>
<:item title="Owner">{@cat.owner}</:item>
<:item title="Owner">{@cat.category}</:item>
</.list>
</div>
<Layouts.app flash={@flash}>
"""
end
end
defmodule LiveViewBasicsWeb.CatLive.Form do
use LiveViewBasicsWeb, :live_view
alias LiveViewBasics.Animals
def mount(params, _sessions, socket) do
socket = apply_action(socket, socket.assigns.live_action, params)
{:ok, socket}
end
def render(assigns) do
~H"""
<Layouts.app flash={@flash}>
<.header>
Cat Form
</.header>
<div class="mb-2">
<.form for={@form} id="cat-form" phx-change="validate" phx-submit="save">
<.input field={@form[:name]} type="text" label="Name" />
<.input field={@form[:color]} type="text" label="Color" />
<.input field={@form[:owner]} type="text" label="Owner" />
<.input field={@form[:category]} type="text" label="Category" />
<footer>
<.button phx-disable-with="Saving...">Save Cat</.button>
</footer>
</.form>
</div>
<Layouts.app flash={@flash}>
"""
end
def handle_event("validate", %{"cat" => cat_params}, socket) do
changeset = Animals.change_cat(socket.assigns.cat, cat_params)
{:noreply, assign(socket, form: to_form(changeset, action: :validate))}
end
def handle_event("save", %{"cat" => cat_params}, socket) do
save_cat(socket, socket.assigns.live_action, cat_params)
end
defp apply_action(socket, :edit, %{"id" => id}) do
cat = Animals.get_cat!(id)
socket
|> assign(:cat, cat)
|> assign(:form, to_form(Animals.change_cat(cat)))
end
defp save_cat(socket, :edit, cat_params) do
case Animals.update_cat(socket.assigns.cat, cat_params) do
{:ok, cat} ->
socket =
socket
|> put_flash(:info, "Cat updated successfully")
|> push_navigate(to: ~p"/cats/#{cat}")
{:noreply, socket}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, form: to_form(changeset))}
end
end
end
# This code already exists if you ran the context generator in the Setup
def update_cat(%Cat{} = cat, attrs) do
cat
|> Cat.changeset(attrs)
|> Repo.update()
end