Last active
December 29, 2023 13:14
-
-
Save objectuser/1854f537c52d64da4403093ce8c0bd6f to your computer and use it in GitHub Desktop.
Form Component with `start_async/3`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Phx17Web.UserLive.FormComponent do | |
use Phx17Web, :live_component | |
alias Phx17.Accounts | |
@impl true | |
def render(assigns) do | |
~H""" | |
<div> | |
<.header> | |
<%= @title %> | |
<:subtitle>Use this form to manage user records in your database.</:subtitle> | |
</.header> | |
<.simple_form | |
for={@form} | |
id="user-form" | |
phx-target={@myself} | |
phx-change="validate" | |
phx-submit="save" | |
> | |
<.input field={@form[:name]} type="text" label="Name" /> | |
<.input field={@form[:age]} type="number" label="Age" /> | |
<:actions> | |
<.button phx-disable-with="Saving...">Save User</.button> | |
</:actions> | |
</.simple_form> | |
</div> | |
""" | |
end | |
@impl true | |
def update(%{user: user} = assigns, socket) do | |
changeset = Accounts.change_user(user) | |
{:ok, | |
socket | |
|> assign(assigns) | |
|> assign_form(changeset)} | |
end | |
@impl true | |
def handle_event("validate", %{"user" => user_params}, socket) do | |
changeset = | |
socket.assigns.user | |
|> Accounts.change_user(user_params) | |
|> Map.put(:action, :validate) | |
{:noreply, assign_form(socket, changeset)} | |
end | |
def handle_event("save", %{"user" => user_params}, socket) do | |
socket | |
|> start_async(:save_user, fn -> | |
case socket.assigns.action do | |
:edit -> Accounts.update_user(socket.assigns.user, user_params) | |
:new -> Accounts.create_user(user_params) | |
end | |
end) | |
|> then(&{:noreply, &1}) | |
end | |
@impl true | |
def handle_async(:save_user, {:ok, {:ok, user}}, socket) do | |
notify_parent({:saved, user}) | |
user |> dbg() | |
{:noreply, | |
socket | |
|> put_flash(:info, "User saved successfully") | |
|> push_patch(to: socket.assigns.patch)} | |
end | |
def handle_async(:save_user, {:ok, {:error, %Ecto.Changeset{} = changeset}}, socket) do | |
{:noreply, assign_form(socket, changeset)} | |
end | |
defp assign_form(socket, %Ecto.Changeset{} = changeset) do | |
assign(socket, :form, to_form(changeset)) | |
end | |
defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Phx17Web.UserLive.Index do | |
use Phx17Web, :live_view | |
alias Phx17.Accounts | |
alias Phx17.Accounts.User | |
@impl true | |
def mount(_params, _session, socket) do | |
{:ok, stream(socket, :users, Accounts.list_users())} | |
end | |
@impl true | |
def handle_params(params, _url, socket) do | |
{:noreply, apply_action(socket, socket.assigns.live_action, params)} | |
end | |
defp apply_action(socket, :edit, %{"id" => id}) do | |
socket | |
|> assign(:page_title, "Edit User") | |
|> assign(:user, Accounts.get_user!(id)) | |
end | |
defp apply_action(socket, :new, _params) do | |
socket | |
|> assign(:page_title, "New User") | |
|> assign(:user, %User{}) | |
end | |
defp apply_action(socket, :index, _params) do | |
socket | |
|> assign(:page_title, "Listing Users") | |
|> assign(:user, nil) | |
end | |
@impl true | |
def handle_info({Phx17Web.UserLive.FormComponent, {:saved, user}}, socket) do | |
{:noreply, stream_insert(socket, :users, user)} | |
end | |
@impl true | |
def handle_event("ping", %{}, socket) do | |
socket | |
|> start_async(:ping, fn -> | |
"One ping only" | |
end) | |
|> then(&{:noreply, &1}) | |
end | |
def handle_event("delete", %{"id" => id}, socket) do | |
user = Accounts.get_user!(id) | |
{:ok, _} = Accounts.delete_user(user) | |
{:noreply, stream_delete(socket, :users, user)} | |
end | |
@impl true | |
def handle_async(:ping, {:ok, message}, socket) do | |
message |> dbg() | |
{:noreply, | |
socket | |
|> put_flash(:info, message) | |
|> push_patch(to: "/users#ping")} | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<.header> | |
Listing Users | |
<:actions> | |
<.link patch={~p"/users/new"}> | |
<.button>New User</.button> | |
</.link> | |
<.link phx-click="ping"> | |
<.button>Ping</.button> | |
</.link> | |
</:actions> | |
</.header> | |
<.table | |
id="users" | |
rows={@streams.users} | |
row_click={fn {_id, user} -> JS.navigate(~p"/users/#{user}") end} | |
> | |
<:col :let={{_id, user}} label="Name"><%= user.name %></:col> | |
<:col :let={{_id, user}} label="Age"><%= user.age %></:col> | |
<:action :let={{_id, user}}> | |
<div class="sr-only"> | |
<.link navigate={~p"/users/#{user}"}>Show</.link> | |
</div> | |
<.link patch={~p"/users/#{user}/edit"}>Edit</.link> | |
</:action> | |
<:action :let={{id, user}}> | |
<.link | |
phx-click={JS.push("delete", value: %{id: user.id}) |> hide("##{id}")} | |
data-confirm="Are you sure?" | |
> | |
Delete | |
</.link> | |
</:action> | |
</.table> | |
<.modal :if={@live_action in [:new, :edit]} id="user-modal" show on_cancel={JS.patch(~p"/users")}> | |
<.live_component | |
module={Phx17Web.UserLive.FormComponent} | |
id={@user.id || :new} | |
title={@page_title} | |
action={@live_action} | |
user={@user} | |
patch={~p"/users"} | |
/> | |
</.modal> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment