<.form for={@form} action={~p"/file-upload/form"} method="post" multipart>
<input type="hidden" name="file_upload_validate[_sent]" value="1" />
<.file_upload field={@form[:attachment]} class="file-upload">
<:label>Attachment</:label>
<:close>
<.heroicon name="hero-x-mark" />
</:close>
<:error :let={msg}>
<.heroicon name="hero-exclamation-circle" class="icon" />
{msg}
</:error>
</.file_upload>
<.action type="submit" class="button button--accent">Submit</.action>
</.form>
defmodule MyAppWeb.FileUploadFormLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
ecto_form =
%MyApp.Form.FileUploadForm{}
|> MyApp.Form.FileUploadForm.changeset_validate(%{})
|> Phoenix.Component.to_form(as: :file_upload_ecto, id: "file-upload-live-form-ecto")
{:ok, assign(socket, :ecto_form, ecto_form)}
end
def handle_event("validate", %{"file_upload_ecto" => params}, socket) do
changeset =
%MyApp.Form.FileUploadForm{}
|> MyApp.Form.FileUploadForm.changeset_validate(params)
|> Map.put(:action, :validate)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset,
action: :validate,
as: :file_upload_ecto,
id: "file-upload-live-form-ecto"
)
)}
end
def handle_event("save", %{"file_upload_ecto" => params}, socket) do
case MyApp.Form.FileUploadForm.changeset_validate(%MyApp.Form.FileUploadForm{}, params) do
%Ecto.Changeset{valid?: true} = changeset ->
_data = Ecto.Changeset.apply_changes(changeset)
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(
MyApp.Form.FileUploadForm.changeset_validate(%MyApp.Form.FileUploadForm{}, params),
as: :file_upload_ecto,
id: "file-upload-live-form-ecto"
)
)}
changeset ->
{:noreply,
assign(
socket,
:ecto_form,
Phoenix.Component.to_form(changeset,
action: :insert,
as: :file_upload_ecto,
id: "file-upload-live-form-ecto"
)
)}
end
end
end
defmodule MyApp.Form.FileUploadForm do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :attachment, :map, virtual: true
end
def changeset(form, attrs \\ %{}) do
cast(form, attrs, [:attachment])
end
def changeset_validate(form, attrs \\ %{}) do
form
|> cast(attrs, [:attachment])
|> validate_attachment_required()
end
defp validate_attachment_required(changeset) do
upload = get_change(changeset, :attachment)
if present_upload?(upload) do
changeset
else
add_error(changeset, :attachment, "can't be blank", validation: :required)
end
end
defp present_upload?(%Plug.Upload{filename: name}) when is_binary(name) and name != "", do: true
defp present_upload?(_), do: false
end