This is my first post in the forum so – hello everyone!
I’m fairly new to Elixir and programming in general so excuse me for my noob question.
I’m exploring the file upload feature in Liveview and am trying to create a drag and drop zone to load up files in the live_file_input
. I read in the documentation that drag & drop support is done by annotating the dropable container with phx-drop-target="<%= @uploads.photo.ref %>".
I have the uploader in a stateful Live Component. this the mount:
def mount(socket) do
{:ok,
socket
|> assign(:uploaded_files, [])
|> allow_upload(:cover_photo,
accept: ~w(.png .jpeg .jpg),
max_file_size: 2_000_000,
external: &presign_entry/2)}
end
and template:
<div class = "flex items-center">
<form id="cover-photo-upload"
phx-change = "validate"
phx-submit = "save" phx-target = "<%=@myself %>" %>
<div class="flex"
id = "dropzone"
phx-hook = "DragDrop"
phx-drop-target="<%= @uploads.cover_photo.ref %>">
<%= live_file_input @uploads.cover_photo %>
<button type="submit" class ="text-white" phx-disable-with = "Uploading">
Upload
</button>
</div>
</div>
Drag & drop isn’t not working for me and it is probably because I am missing something. I’m sure if I have to implement anything on the javascript side. Right now, I have a Hook that highlights the container on dragenter
and dragover
.
Hooks.DragDrop = {
mounted() {
let dropArea = document.getElementById(this.el.id);
[("dragenter", "dragover", "dragleave", "drop")].forEach((eventName) => {
dropArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
["dragenter", "dragover"].forEach((eventName) => {
dropArea.addEventListener(eventName, highlight, false);
});
["dragleave", "drop"].forEach((eventName) => {
dropArea.addEventListener(eventName, unhighlight, false);
});
function highlight(e) {
dropArea.classList.add("bg-red-400");
}
function unhighlight(e) {
dropArea.classList.remove("bg-red-400");
}
},
};
Thanks for your help!
Pedro