
Create A Drop Zone File Upload Form Field Using Alpine.js
Learn how to make a nice drop zone file upload field using Alpine.js

Example Field
Getting Started
This tutorial utilizes Alpine.js and Tailwind CSS but the same principals can be applied to vanilla JavaScript and standard CSS.
Standard File Input
We start off with the standard file
type input like this.
/exampleForm.html
Prepare Alpine.js
Ok, so first were going to class="hide"
the standard file input because we don't want too see the ugly standard file input any more. We will use JavaScript to inject the files into the input instead! Go ahead and put an x-ref="fileInput"
on it too so we can easily target it later.
Then were going to wrap the input and label in a div
an put a x-data={}
on it with a files: []
array and dragActive: false
inside of it.
/exampleForm.html
Add Styles and Image Previews
Next were going to add some styles to get this thing looking good and utilize Alpine's x-for
to loop over the files
array in our x-data
. Notice how were supplying a :key="index"
here? These keys are necessary because its possible for users to add and remove their assets.
Also change the label text to Drop files here or click to upload
to tell users they can drag files in.
Now you should have something that looks like the example but doesn't function when you click or drag images into it. That's our next step.
/exampleForm.html
Alpine.js Functions
Ok cool, this is where we add in the functionality bits. Were going to add 5 function into the x-data
block.
Let's name the first one dropFile()
, this one handles the @drop
event when a user drags and drops a file into the field. The function puts the file into our files
array, then adds them into a DataTransfer
object, and finally adds the file to the input we hid.
Great! Now we need to do the same thing when a user clicks and selects a file using the file selector. This function is called handleFiles()
and it's attached to the hidden input using an Alpine @change
event listener.
Nice, that should get the files into the field but we also need a way to let users remove files. That's where our removeFile()
function steps in. The function removes the file based on its index number and then also will update the input field. Attach this file to a @click
event on the × button. Let's also add stop.prevent
otherwise clicking it will also open up the file selector.
The next two functions dragOver()
and dragLeave()
are just functions to trigger some CSS changes when a user drags over and out of the field. Connect these up to the @dragOver
and @dragLeave
event listeners. Then we can add a :css
tag to the main div and change the border color to blue to indicate some action.
Add a :src
tag to the image in the template and set it to URL.createObjectURL(file)
which will show a nice little preview of the image uploaded!
Use the code below for reference. You should now have a functioning file uploader!
/exampleForm.html
Improvements!
Oh cool, I see a way to improve this a bit and save us some repeated code. Lets make a 6th function called updateFileInput()
add the DataTransfer()
parts and then we can use it in dropFile()
,handleFiles()
, andremoveFile()
.
Another thing I forgot, was to take into account users uploading files other than images. So here I've added x-if
conditionals inside the file preview template to check for the file type and display a file icon if the file isn't an image.
Behold, the code below!
/exampleForm.html