参考資料
- allow_uploadでアップロードできるファイルを指定
- live_file_inputタグはファイルの受付画面を作る
- handle_event("validate", _params, socket)で検証
- handle_event("save", _params, socket)で保存
プロジェクトの準備
$ phx.new upload_experiment --no-ecto
ソース追加
lib/upload_experiment_web/live/upload_live.ex
defmodule UploadExperimentWeb.UploadLive do
use UploadExperimentWeb, :live_view
@impl Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok,
socket
|> assign(:uploaded_files, [])
|> allow_upload(:avatar, accept: ~w(.png), max_entries: 2)}
end
@impl Phoenix.LiveView
def handle_event("validate", _params, socket) do
{:noreply, socket}
end
@impl Phoenix.LiveView
def handle_event("cancel-upload", %{"ref" => ref}, socket) do
{:noreply, cancel_upload(socket, :avatar, ref)}
end
@impl Phoenix.LiveView
def handle_event("save", _params, socket) do
uploaded_files =
consume_uploaded_entries(socket, :avatar, fn %{path: path}, _entry ->
dest = Path.join("priv/static/images/uploads", Path.basename(path))
# You will need to create `priv/static/uploads` for `File.cp!/2` to work.
File.cp!(path, dest)
{:ok, ~p"/images/uploads/#{Path.basename(dest)}"}
end)
{:noreply, update(socket, :uploaded_files, &(&1 ++ uploaded_files))}
end
defp error_to_string(:too_large), do: "Too large"
defp error_to_string(:too_many_files), do: "You have selected too many files"
defp error_to_string(:not_accepted), do: "You have selected an unacceptable file type"
end
lib/upload_experiment_web/live/upload_live.html.heex
<form id="upload-form" phx-submit="save" phx-change="validate">
<.live_file_input upload={@uploads.avatar} />
<button type="submit">Upload</button>
</form>
<section phx-drop-target={@uploads.avatar.ref}>
<%!-- render each avatar entry --%>
<%= for entry <- @uploads.avatar.entries do %>
<article class="upload-entry">
<figure>
<.live_img_preview entry={entry} />
<figcaption><%= entry.client_name %></figcaption>
</figure>
<%!-- entry.progress will update automatically for in-flight entries --%>
<progress value={entry.progress} max="100"> <%= entry.progress %>% </progress>
<%!-- a regular click event whose handler will invoke Phoenix.LiveView.cancel_upload/3 --%>
<button type="button" phx-click="cancel-upload" phx-value-ref={entry.ref} aria-label="cancel">×</button>
<%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.avatar, entry) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>
</article>
<% end %>
<%!-- Phoenix.Component.upload_errors/1 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.avatar) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>
</section>
lib/upload_experiment_web/router.ex
defmodule UploadExperimentWeb.Router do
# 〜省略〜
scope "/", UploadExperimentWeb do
pipe_through :browser
+ live "/up", UploadLive, :index
get "/", PageController, :home
end
# 〜省略〜
end
下記のフォルダーを作成する
priv/static/images/uploads
実行
下記にアクセス
http://localhost:4000/up
ソース(github)