Skip to content

Instantly share code, notes, and snippets.

@chrismccord
Last active April 5, 2023 00:33
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrismccord/4dec0b6b410c0345b7dc25e60e15ed6d to your computer and use it in GitHub Desktop.
Save chrismccord/4dec0b6b410c0345b7dc25e60e15ed6d to your computer and use it in GitHub Desktop.
upload_example.ex
defmodule UploadDemoWeb.UploadLive do
use UploadDemoWeb, :live_view
def render(assigns) do
~H"""
<%= for {_ref, err} <- @uploads.avatar.errors do %>
<div class="alert alert-danger"><%= humanize(to_string(err)) %></div>
<% end %>
<div id="entries">
<%= for entry <- @uploads.avatar.entries do %>
<div id={"entry-#{entry.ref}"} class="row">
<%= live_img_preview entry, width: 75 %>
<h5><%= entry.client_name %></h5>
<div class="progress-bar" style={"width: #{entry.progress};"}></div>
<button type="button" phx-click="cancel-upload" phx-value-ref={entry.ref}>
<i class="far fa-trash"></i>
</button>
</div>
<% end %>
</div>
<form phx-change="validate" phx-submit="save" id="upload-form">
<%= live_file_input @uploads.avatar %>
<%= if Enum.any?(@uploads.avatar.entries) do %>
<button type="submit" phx-disable-with="uploading...">
upload <%= length(@uploads.avatar.entries) %> files
</button>
<% end %>
</form>
<div id="files">
<h5>uploaded files (<%= length(@uploaded_files) %>)</h5>
<%= for url <- @uploaded_files do %>
<img src={url} width="150"/>
<% end %>
</div>
"""
end
def mount(_params, session, socket) do
{:ok,
socket
|> assign(:uploaded_files, [])
|> allow_upload(:avatar, accept: ~w(.jpeg .png), max_entries: 3)}
end
def handle_event("save", _params, socket) do
uploaded_files =
consume_uploaded_entries(socket, :avatar, fn %{} = meta, entry ->
[ext | _] = MIME.extensions(entry.client_type)
dest = Path.join("priv/static/uploads", Path.basename(meta.path) <> "." <> ext)
File.cp!(meta.path, dest)
Routes.static_path(socket, "/uploads/#{Path.basename(dest)}")
end)
{:noreply,
socket
|> put_flash(:info, "#{length(uploaded_files)} file(s) uploaded")
|> update(:uploaded_files, &(&1 ++ uploaded_files))}
end
def handle_event("cancel-upload", %{"ref" => ref}, socket) do
{:noreply, cancel_upload(socket, :avatar, ref)}
end
def handle_event("validate", _params, socket) do
{:noreply, socket}
end
end
@baskint
Copy link

baskint commented Sep 23, 2021

amazing... quite possibly the shortest drag & drop code for any web framework 👏 , was going to comment on the ~H sigil but all i had to do is keep on reading...

@cachance7
Copy link

If anyone happens upon this snippet from content around the web, you're better served by looking at the implementation in the official liveview docs now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment