Drag and Drop File Upload with jQuery and AJAX

Drag and drop is a simple way to allow users to upload their files by dropping them into the container. Nowadays most websites allow uploading using both drag and drop and the file browse e.g. PushBullet, Facebook, SlideShare, etc.

I am using AJAX to save the file to the server which triggers when the file dropped on the target container.

In this tutorial, I show how you can implement a similar type of feature in your project and show a thumbnail when the file successfully uploaded using jQuery AJAX and PHP.

Drag and Drop File Upload with jQuery and AJAX


Contents

  1. HTML
  2. CSS
  3. PHP
  4. jQuery
  5. Output
  6. Conclusion

1. HTML

I created a <div class="container"> which contains the file element and a <div class="upload-area" id="uploadfile"> container.

I am using this <div> as file uploading area where the user can drag and drop the file or open File Dialog Box by clicking on it.

Completed Code

<!doctype html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="script.js" type="text/javascript"></script>
    </head>
    <body >

        <div class="container" >
            <input type="file" name="file" id="file">
            
            <!-- Drag and Drop container-->
            <div class="upload-area"  id="uploadfile">
                <h1>Drag and Drop file here<br/>Or<br/>Click to select file</h1>
            </div>
        </div>

    </body>
</html>

2. CSS

.upload-area{
    width: 70%;
    height: 200px;
    border: 2px solid lightgray;
    border-radius: 3px;
    margin: 0 auto;
    margin-top: 100px;
    text-align: center;
    overflow: auto;
}

.upload-area:hover{
    cursor: pointer;
}

.upload-area h1{
    text-align: center;
    font-weight: normal;
    font-family: sans-serif;
    line-height: 50px;
    color: darkslategray;
}

#file{
    display: none;
}

/* Thumbnail */
.thumbnail{
    width: 80px;
    height: 80px;
    padding: 2px;
    border: 2px solid lightgray;
    border-radius: 3px;
    float: left;
}

.size{
    font-size:12px;
}

3. PHP

Create a new upload directory and upload.php file.

Use upload directory to store files and also added default.png image which uses as a thumbnail for non-image type file.

Upload file to upload directory and check file is image or not. If image then assign $location to $src.

Initialize $return_arr Array with file name, size, and location.

Return JSON response.

Completed Code

<?php

/* Getting file name */
$filename = $_FILES['file']['name'];

/* Getting File size */
$filesize = $_FILES['file']['size'];

/* Location */
$location = "upload/".$filename;

$return_arr = array();

/* Upload file */
if(move_uploaded_file($_FILES['file']['tmp_name'],$location)){
    $src = "default.png";

    // checking file is image or not
    if(is_array(getimagesize($location))){
        $src = $location;
    }
    $return_arr = array("name" => $filename,"size" => $filesize, "src"=> $src);
}

echo json_encode($return_arr);

4. jQuery

The below code stops the page from redirect when the file drop on the page.

 // preventing page from redirecting
 $("html").on("dragover", function(e) {
    e.preventDefault();
    e.stopPropagation();
    $("h1").text("Drag here");
 });

 $("html").on("drop", function(e) { e.preventDefault(); e.stopPropagation(); });

This removes page default functionality.

Drag & Drop

When the file is dropped on <div class="upload-area"> then storing the file in a variable and creating a FormData Object fd.

Using append() method to store the file in FormData variable.

Passing FormData Object variable in uploadData() function.

From where send AJAX request and using FormData variable as data. When the AJAX successfully callback, passing the response to addThumbnail() function which creates a new thumbnail and shows its information (name and size).

If the uploaded file is an image then show its image otherwise show the default image.

Click

When the user clicks on the upload area then fire the click event on the file element (id=uploadfile). Onchange event uploading the file and showing the thumbnail same as drag & drop.

Completed Code

$(function() {

    // preventing page from redirecting
    $("html").on("dragover", function(e) {
        e.preventDefault();
        e.stopPropagation();
        $("h1").text("Drag here");
    });

    $("html").on("drop", function(e) { e.preventDefault(); e.stopPropagation(); });

    // Drag enter
    $('.upload-area').on('dragenter', function (e) {
        e.stopPropagation();
        e.preventDefault();
        $("h1").text("Drop");
    });

    // Drag over
    $('.upload-area').on('dragover', function (e) {
        e.stopPropagation();
        e.preventDefault();
        $("h1").text("Drop");
    });

    // Drop
    $('.upload-area').on('drop', function (e) {
        e.stopPropagation();
        e.preventDefault();

        $("h1").text("Upload");

        var file = e.originalEvent.dataTransfer.files;
        var fd = new FormData();

        fd.append('file', file[0]);

        uploadData(fd);
    });

    // Open file selector on div click
    $("#uploadfile").click(function(){
        $("#file").click();
    });

    // file selected
    $("#file").change(function(){
        var fd = new FormData();

        var files = $('#file')[0].files[0];

        fd.append('file',files);

        uploadData(fd);
    });
});

// Sending AJAX request and upload file
function uploadData(formdata){

    $.ajax({
        url: 'upload.php',
        type: 'post',
        data: formdata,
        contentType: false,
        processData: false,
        dataType: 'json',
        success: function(response){
            addThumbnail(response);
        }
    });
}

// Added thumbnail
function addThumbnail(data){
    $("#uploadfile h1").remove(); 
    var len = $("#uploadfile div.thumbnail").length;

    var num = Number(len);
    num = num + 1;

    var name = data.name;
    var size = convertSize(data.size);
    var src = data.src;

    // Creating an thumbnail
    $("#uploadfile").append('<div id="thumbnail_'+num+'" class="thumbnail"></div>');
    $("#thumbnail_"+num).append('<img src="'+src+'" width="100%" height="78%">');
    $("#thumbnail_"+num).append('<span class="size">'+size+'<span>');

}

// Bytes conversion
function convertSize(size) {
    var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
    if (size == 0) return '0 Byte';
    var i = parseInt(Math.floor(Math.log(size) / Math.log(1024)));
    return Math.round(size / Math.pow(1024, i), 2) + ' ' + sizes[i];
}

5. Output


6. Conclusion

I showed how you implement drag and drop file upload functionality in your project and I didn’t add any type of restriction while uploading the file in PHP which you can add as per your requirement.

If you found this tutorial helpful then don't forget to share.
Are you want to get implementation help, or modify or extend the functionality of this script? Submit paid service request.

35 thoughts on “Drag and Drop File Upload with jQuery and AJAX”

    • Add this on top of your .js file (after $(function() {) to support IE compatibility.
      (It prevents Internet Explorer’s default dragging action):

      document.ondragstart = function () { return false; };

      Reply
  1. Quick question Yogesh,

    How would you implement file type restrictions?
    When ever i try and add a function to upload.php any echo error message breaks it.

    Thanks!

    Reply
    • You can check the file extension while file uploading

      $array = explode(‘.’, $_FILES[‘file’][‘name’]);
      $extension = end($array);

      and if the extension is valid then execute the move_uploaded_file() method.

      Reply
  2. Hey thanks for your help !

    But i’ve this error when i use your code :

    Failed to load resource: the server responded with a status of 500 (PLG_SYSTEM_REDIRECT_ERROR_UPDATING_DATABASE)

    Do you have some idea ?

    Reply
  3. Nice tutorial.
    downloaded it and it’s working well in my computer (ngInx server)
    I’m really happy I found it, because I’m working with one web project
    and planning upload there…
    I Tested it with firefox,opera,chrome
    Thanks!

    Reply
  4. Hi,

    Works great but I notice that the thumbnail are rotated if the aspect ration is different that the others. IE; if the original picture is tall, the thumbnail is rotated. If wide, it is not. May freak out the person I am building this for.

    Is there a way to turn this off? I can deal with the css and other stuff.

    Thanks!

    Reply
  5. Hi,
    It’s a Wonderful code, it’s just what I needed.
    Many many many thanks guy 😉
    I modified small things to control the format, max size and limit the number of max uploaded images… works really great 🙂
    If you vant, I would be happy to provide you with changes as required.

    I’m missing a tool I can’t develop !
    How to propose to delete thumbnail with his image and update the remaining images.
    For ex : I’ve posted 4 images, have 4 thumbnails and finally want to delete only the 3rd ?
    Best regards

    Reply
  6. Thank you for sharing this great work of yours.
    I have a rather strange problem,
    The file that I select via the file interface gets uploaded just fine, but the file that I drag and drop does not, it fails the mime_type check in PHP even if it is the same file. I printed the formdata on both the drop and the select file and it shows the same.
    Any ideas? :O

    Reply
  7. Great tutorial – well written and clear.

    I’m actually using Python rather than PHP, so I had to rewrite the server-side code, and I included multiple files support which I don’t think the PHP code does.
    I also need multiples of these on one page, so I modified it to support multiple unique Id’s rather than just one, and to include an additional field to identify which product the images were for. So much easier than starting from scratch!

    Reply

Leave a Comment