-
Notifications
You must be signed in to change notification settings - Fork 935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
live_file_input component and multiple files not validating for submitting #3319
Comments
Please try to update LV, 0.20.15 had a bug with patching form contents. |
Hi @SteffenDE I'm on 0.20.17 now, exactly the same. I can't see that I've missed any config or code changes to handle this. The only difference I can see that is needed is going from The
Thanks. |
Any ideas? |
@ghenry Sorry, I'm very busy at the moment and didn't have the time to look into it yet. It'd be great if you could create a single file script to reproduce the problem. This should be a good start: https://github.com/phoenixframework/phoenix_live_view/blob/main/.github/single-file-samples/main.exs |
Will do. That will also allow me to prove if I've got some cruft blocking this simple thing from working. |
Will get this example over in the next few days. Was away on holiday. |
I believe this example highlights the issue here. We were working on upgrading libraries/elixir/otp and discovered this in our regession cases. This seems to only be an issue when In the example code below I have set Repro Steps
Expected BehvaiorError shown and files do not begin uploading Actual BehaviorError is shown and files begin uploading Application.put_env(:sample, Example.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 5001],
server: true,
live_view: [signing_salt: "aaaaaaaa"],
secret_key_base: String.duplicate("a", 64),
pubsub_server: Example.PubSub
)
Mix.install([
{:plug_cowboy, "~> 2.5"},
{:jason, "~> 1.0"},
{:phoenix, "~> 1.7"},
# please test your issue using the latest version of LV from GitHub!
{:phoenix_live_view, github: "phoenixframework/phoenix_live_view", branch: "main", override: true},
])
# build the LiveView JavaScript assets (this needs mix and npm available in your path!)
path = Phoenix.LiveView.__info__(:compile)[:source] |> Path.dirname() |> Path.join("../")
System.cmd("mix", ["deps.get"], cd: path, into: IO.binstream())
System.cmd("npm", ["install"], cd: Path.join(path, "./assets"), into: IO.binstream())
System.cmd("mix", ["assets.build"], cd: path, into: IO.binstream())
defmodule Example.ErrorView do
def render(template, _), do: Phoenix.Controller.status_message_from_template(template)
end
defmodule Example.HomeLive do
use Phoenix.LiveView, layout: {__MODULE__, :live}
def mount(_params, _session, socket) do
socket =
socket
|> assign(:uploaded_files, [])
|> allow_upload(:avatar, auto_upload: true, accept: ~w(.jpg .jpeg), max_entries: 2, max_file_size: 1_000_000_000)
{:ok, socket}
end
def render("live.html", assigns) do
~H"""
<script src="/assets/phoenix/phoenix.js"></script>
<script src="/assets/phoenix_live_view/phoenix_live_view.js"></script>
<%!-- uncomment to use enable tailwind --%>
<%!-- <script src="https://cdn.tailwindcss.com"></script> --%>
<script>
let liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket)
liveSocket.connect()
</script>
<style>
* { font-size: 1.1em; }
</style>
<%= @inner_content %>
"""
end
def render(assigns) do
~H"""
<form id="upload-form" phx-submit="save" phx-change="validate">
<.live_file_input upload={@uploads.avatar} />
<button type="submit">Upload</button>
</form>
<section>
<%!-- render each avatar entry --%>
<%= for entry <- @uploads.avatar.entries do %>
<article class="upload-entry">
<figure>
<.live_img_preview entry={entry} style="width: 250px;"/>
<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>
"""
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(["/tmp"])
# # You will need to create `priv/static/uploads` for `File.cp!/2` to work.
# File.cp!(path, dest)
# {:ok, "/tmp/#{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(:not_accepted), do: "You have selected an unacceptable file type"
defp error_to_string(:too_many_files), do: "You have selected too many files"
end
defmodule Example.Router do
use Phoenix.Router
import Phoenix.LiveView.Router
pipeline :browser do
plug(:accepts, ["html"])
end
scope "/", Example do
pipe_through(:browser)
live("/", HomeLive, :index)
end
end
defmodule Example.Endpoint do
use Phoenix.Endpoint, otp_app: :sample
socket("/live", Phoenix.LiveView.Socket)
plug Plug.Static, from: {:phoenix, "priv/static"}, at: "/assets/phoenix"
plug Plug.Static, from: {:phoenix_live_view, "priv/static"}, at: "/assets/phoenix_live_view"
plug(Example.Router)
end
{:ok, _} = Supervisor.start_link([{Phoenix.PubSub, name: Example.PubSub}, Example.Endpoint], strategy: :one_for_one)
Process.sleep(:infinity) |
@SteffenDE I did some testing with the above example and it seems this behavior showed up in I haven't had a chance to test any changes locally, but I'm leaning towards this change between the |
We have this in the changelog for 0.20:
which might be related? I'm sadly not too familiar with the upload code, maybe @chrismccord can have a look. |
@SteffenDE I'm curious as to the intention here. Given 3 files, two jpegs and one png, to a If the answer is B, wouldn't that present issues if the number of files given exceeds the |
I don't have auto upload enabled:
|
I can file a separate bug, but I believe both situations are rooted in the upload refactoring. I'll defer to @SteffenDE and @ghenry on this. |
Environment
Elixir version (elixir -v): Erlang/OTP 26 [erts-14.2.5] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns]
Elixir 1.16.2 (compiled with Erlang/OTP 26)
Phoenix version (mix deps): phoenix (Hex package) (mix)
locked at 1.7.14 (phoenix) c7859bc5
Phoenix LiveView version (mix deps): phoenix_live_view (Hex package) (mix)
locked at 0.20.15 (phoenix_live_view) 45c48ad1
Operating system: Fedora 40 x86_64 Workstation
Browsers you attempted to reproduce this bug on (the more the merrier): Firefox and Chrome latest
Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: Yes, same
Actual behavior
Multiple files are accepted, but input field shows "Please select file" when Submit is clicked. When switching back to max_entries: 1, all is OK.
Expected behavior
Submit works and multiple files are uploaded.
Thanks for taking the time to read this and for the wonderful Phoenix and Phoenix LiveView.
The text was updated successfully, but these errors were encountered: