Drag and Drop File Upload with jQuery and AJAX

Utilizing the drag and drop functionality presents a user-friendly method to enable file uploads by effortlessly dropping files into a designated container. Nowadays, numerous websites offer the convenience of uploading files through both drag and drop and traditional file browsing methods, such as PushBullet, Facebook, SlideShare, and many others.

To achieve this functionality, I employ AJAX to seamlessly save the files to the server, which is triggered as soon as a file is dropped onto the specified target container.

Within this tutorial, I show how you can seamlessly implement a similar feature into your own project. By using jQuery AJAX and PHP, you can not only enable the drag and drop file upload but also showcase a thumbnail preview of the successfully uploaded file.

Drag and Drop File Upload with jQuery and AJAX


Table of Content

  1. HTML Structure for Drag and Drop File Upload
  2. CSS Styling
  3. PHP – File Upload and Return File Details for Preview
  4. jQuery – Drag and Drop File Upload
  5. Output
  6. Conclusion

1. HTML Structure for Drag and Drop File Upload

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.

<!doctype html>
<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/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 Styling

.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 – File Upload and Return File Details for Preview

Setting Up the Upload Folder and “upload.php” File:

Create upload.php file to handle file upload functionality and create an upload folder where all uploaded files will be stored.

Handling File Storage and Thumbnail:

Utilize the upload folder to store the uploaded files. For non-image files, include a default thumbnail named default.png that will be used as the thumbnail representation.

Checking File Type:

When a file is uploaded, verify whether it is an image or not. If it is indeed an image, assign the file location to the variable $src for future use as the thumbnail source.

Preparing the Return Array:

Initialize $return_arr array to hold essential file details such as the file name, size, and location.

Returning Data in JSON Format:

After processing the uploaded file, encode the $return_arr array into JSON format. This enables the seamless communication of file details to the front-end, allowing for smooth integration and real-time file previews.

<?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 – Drag and Drop File Upload

Preventing Default Page Actions:

This code prevents the default page redirect behavior when files are dragged over the page. It displays the text Drag here inside an h1 element to indicate the drag action.

// 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(); });

Handling Drag and Drop Events:

Defines event handlers for the dragenter, dragover, and drop events on the .upload-area element. When a file is dragged over this area, the text Drop is displayed in the h1 element.

Uploading File on Drop:

Upon dropping a file on the .upload-area, retrieves the dropped file and creates a FormData object (fd) to store it. The file is then passed to the uploadData() function to initiate an AJAX request for file upload.

Handling File Selection via Click:

When the user clicks on the upload area (id=”uploadfile”), it triggers a click event on the file input element (id=”file”). The onchange event of the file input allows the user to select a file from their local system, which is then uploaded using the uploadData() function.

Sending AJAX Request for File Upload:

The uploadData() function sends an AJAX request to the server-side script upload.php with the selected or dropped file data in FormData format. The server processes the file upload and returns a JSON response with details about the uploaded file.

Displaying Thumbnails:

Upon a successful AJAX response, the addThumbnail() function is called to display the uploaded file’s thumbnail and its corresponding information, such as the file name and size. If the uploaded file is an image, its thumbnail is shown; otherwise, a default image is displayed.

Bytes Conversion:

Created convertSize() function to convert the file size from bytes to a more human-readable format (KB, MB, etc.), making it easier for users to understand the file’s size.

$(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

View Output


6. Conclusion

I have demonstrated how to implement drag and drop file upload functionality using jQuery, AJAX, and PHP. Customize and add restrictions as needed for your project’s requirements. Enhance user experience by providing an intuitive and secure file uploading system.

For an alternative approach, explore the tutorial on implementing Drag & Drop file upload using the Dropzone library.

If you found this tutorial helpful then don't forget to share.