Daring Designs uses cookies to enhance your experience, analyze site traffic, and improve our services. By clicking dismiss, you agree to our use of cookies.

Skip to main content
Daring Designs
Contact Search

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