How to upload files using drag n drop method. HTML5: Uploading Files with Drag-and-drop

This markup doesn"t have anything specifically to do with drag and drop. It"s just a normal, functional, albeit with some extra HTML elements for potential states.

Choose a file or drag it here. Upload Done! Error! .

We"ll hide those states until we need them:

Box__dragndrop, .box__uploading, .box__success, .box__error ( display: none; )

A little explanation:

  • Regarding states: .box__uploading element will be visible during the Ajax process of file upload (and the others will still be hidden). Then .box__success or .box__error will be shown depending on what happens.
  • input and label are the functional parts of the form. I wrote about styling these together in my post about customizing file inputs. In that post I also described the purpose of attribute. The input and label also serve as an alternative for selecting files in the standard way (or the only way if drag and drop isn't supported).
  • .box__dragndrop will be shown if a browser supports drag and drop file upload functionality.
Feature detection

We can"t 100% rely on browsers supporting drag and drop. We should provide a fallback solution. And so: feature detection. Drag & drop file upload relies on a number of different JavaScript API"s, so we"ll need to check on all of them.

Allow the user to upload files to the server by dragging them, for example, from the desktop. Moreover, it would be possible to drag and drop several files at once.

Solution

As you can see from the example above, files are sent to the server immediately after selection. Let's send them by event:

Window.onload = function())( var uploader = new qq.FileUploader(( autoUpload: false, element: document.getElementById("file-uploader"), action: "php/upload.php" )); $("# startUpload").on("click", function())( uploader.uploadStoredFiles(); )); );

Result

In general, the plugin has many options and settings, and there are callbacks. All this is described. Fineuploader is under constant development, so when linking, I recommend visiting the repository and downloading the latest version.

Stylization

The plugin creates its structure based on the .qq-uploader class, all elements are described in css file fileuploader.css

On a note

If the donkeys stubbornly refuse to work, open the script and look for the line there:

Var form = qq.toElement("");

and change to:

Var form = qq.toElement("");

We continue to create our drag and drop download, and today we will write our server and start writing JavaScript code.

In the last article we wrote an index.html file and styles for it. Today we will write a server that will download files and send information about them back to the script, but first let's talk about what file structure we will have:

  • .htaccess
  • index.html
  • style.css
  • upload.php
  • uploads

Everything is clear with the index.html and style.css files. We simply set the encoding in the .htaccess file so that there are no problems.

AddDefaultCharset UTF-8

The upload.php file will upload files to the server in the uploads folder.

So let's start with php. To do this, open the upload.php file and write the following:

At the beginning of the file we write a Content-Type header to tell the browser that it will receive json. Then we create an empty $uploaded array and check if there are any files at all. If yes, then we go through them and upload them to our uploads directory, and also fill our main $uploaded array with subarrays that will contain information about the files. In our case, this is the name of the file and its location. Finally, we convert our array to json and output it. As you can see, the server is not complicated at all.

Now let's move on to the index.html file


Drag files here

(function() (
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = function() (
this.className = "dropzone dragover";
this.innerHTML = "Release mouse";
return false;
};

Dropzone.ondragleave = function() (


return false;
};

Dropzone.ondrop = function(e) (
this.className = "dropzone";
this.innerHTML = "Drag files here";
e.preventDefault();
};
})();

Remember the .dragover class we wrote in the last article, and I said that it would be used when there was some file above our block? This is, in fact, what we have done now. When some file appears above the block, the ondragover event is fired, where we simply add our .dragover class and change the text to "Release the mouse". When we move the mouse with the file away from our block, the ondragleave event is triggered, where we return everything to its original position. When a person “drops” a file into our block, the ondrop event is triggered. There we change everything again, as it was at the beginning, otherwise our .dragover class will “freeze” and cancel the default behavior. If we don't do this, our file will simply open in the browser, which is not what we want.

Greetings to all! In this article I want to talk about several of my experiments with HTML5. I'll start from afar. We all periodically have to work with various web interfaces and often have the feeling that this work could be organized more efficiently.

Perhaps in some cases the service developers are to blame, but often the problem lies in the limitations imposed by browsers. Let's consider uploading files to the server. In most cases, you will be presented with a standard field with a button to select a file from your computer and/or a field in which you can specify the URL of a file located somewhere on the Web.

Downloading files from local computer Let’s not touch it for now, I plan to publish a separate post on this topic, let’s look at downloading from a remote server.

Problems start from the very first step. Even if you clearly understand where to look for a URL and are good at using tools like firebug, it will still take a few clicks to get the right address. It would be much more convenient to simply drag the desired image from one browser window to another.

I will show an example of the implementation of such an interface in this article. If you want, you can see how it works on the demo page or .

Note! This example only works in Google browser Chrome. In theory, Firefox and Safari support all the necessary technologies, but I haven’t figured them out yet. I mainly took pictures from Wikipedia as objects for dragging. Several problems were noticed related to non-Latin characters in the URLs of images, but in order not to overload the example with checks and transformations, I left them as is.

Principle of operation

The HTML5 standard provides support for dragging and dropping page objects. By the way, I have already shown an example of the simplest implementation of D&D - Drag & Drop using HTML5. And besides, there are quite a few JavaScript libraries that implement D&D support.

But here it is important to understand that if you need to “drag” pictures from third-party resources, then you won’t be able to use libraries. Because you won't be able to add your JS code to someone else's page. And in order to download a picture, we need to get its URL, i.e. The browser must also transmit its parameters along with the dragged object (for example, the src attribute of an image or the entire img tag).

In this case, we can create a “receiver” of pictures on our page. This will be a regular div with a drop event handler assigned. If the user “drops” the image above this div, the handler will be called and in the first parameter it will receive an object containing information about the image being dragged.

Implementation

Let's start with our application page.

Images Upload


It contains two blocks: images – here we will show the downloaded images and img_target – you need to drag pictures onto this block. At the bottom of the page we connect the jQuery library and the main.js script, which will send information about the dragged images to the server.

Let's look at main.js
$(function() (
$("#img_target")
.bind("dragenter", function(event) (
$(this).addClass("drop_here");
return false;
})
.bind("dragleave", function(event) (

return false;
})
.bind("dragover", function(event) (
return false;
})
.bind("drop", function(event) (
$(this).removeClass("drop_here");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(data);
$.post("upload.php", ("file_url":img_data), function(res) (
var response = eval("(" + res + ")");
$("#images").append($(""));
});
return true;
});
});
Here we assign handlers to the dragenter, dragleave and dragover events. All of them should simply return false and, in order to somehow inform the user that the image can be “dropped”, in the dragenter handler we set the CSS class drop_here for the receiver block. Most of the work is done in the drop event handler. When this event occurs, we read information about the “reset” object and “cut” the value of the src attribute, i.e. URL of the image. The information is transferred in the event.originalEvent.dataTransfer object.

Then we form a regular AJAX request and pass the found URL as a parameter. The server script (upload.php) will receive the URL of the image on the remote server and upload it. And in response to the AJAX request, it will send the new URL of the loaded image. In turn, the AJAX request handler will create an img tag and insert it into the images block. Thus, the downloaded pictures will appear above the download field.

Consider upload.php

The operating principle is as follows. We read the URL of the image and try to download it. If the image is uploaded, save it to the upload folder. Receiving an image from a remote server is carried out using the fread functions. The file is read in 1kB blocks. This approach allows you to interrupt the download of a file if its size exceeds a specified limit (in in this case 300kB).

After downloading the file, we form a URL for it and send it to the browser in JSON format. As you can see, implementing such a bootloader is not difficult. And it is quite convenient to use. Naturally, the main drawback is the support of HTML5 by browsers, or rather the lack thereof. However, if you are creating an interface for employees of a company, and you can specify the type of browser, then HTML5 can be used.

In this tutorial we will make a small AJAX file upload form that will allow visitors to upload files using or using a normal file selection.

We will use the jQuery File Upload and jQuery Knob plugins to display the .

Because the form will be able to upload files in two ways, it will work even if drag/drop is not supported.

HTML

As usual, let's start with HTML5 markup:

Mini Ajax File Upload Form Drop Here Browse

In the tag of our document, we connect Google fonts Webfonts, and before the closing tag - JavaScript libraries: jQuery, jQuery Knob and jQuery File Upload.

The main element of the page is the #upload form. Inside it is the #drop element (accepts files using drag&drop) and a list in which downloaded files will be displayed. Markup that will be generated for uploaded files:

  • Sunset.jpg 145 KB

  • The input element will be hidden with using CSS. It is needed for initialization jQuery plugin Knob that will draw the file. Input has data-* attributes which are used to update the scale. Later, when we track the loading progress, we will update these values ​​to redraw the scale. span will contain a green check mark or a red cross.

    jQuery

    The visitor will have 2 ways to download the file:

    • Drag the file into the browser window (does not work in IE).
    • By clicking on the browse button. A click on the hidden input will be simulated and the system file selection window will be shown. Note that input has a multiple parameter, which will allow you to select many files at once.

    When files are selected, they are queued for later automatic download:

    $(function())( var ul = $("#upload ul"); $("#drop a").click(function())( // simulate clicking on the file selection field $(this).parent(). find("input").click(); )); // initialize the jQuery plugin File Upload $("#upload").fileupload(( // this element will accept files dropped onto it dropZone: $("#drop" ), // The function will be called when the file is queued add: function (e, data) ( var tpl = $("

  • "); // output the file name and size tpl.find("p").text(data.files.name) .append(" " + formatFileSize(data.files.size) + ""); data.context = tpl.appendTo(ul); // initializing the jQuery Knob plugin tpl.find("input").knob(); // tracking clicks on the cancel icon tpl.find("span").click (function())( if(tpl.hasClass("working"))( jqXHR.abort(); ) tpl.fadeOut(function())( tpl.remove(); )); )); // Automatically load the file when adding to the queue var jqXHR = data.submit(); ), progress: function(e, data)( // Calculating the loading percentage var progress = parseInt(data.loaded / data.total * 100, 10); // updating the scale data.context.find("input").val(progress).change(); if(progress == 100)( data.context.removeClass("working"); ) ), fail:function(e, data) ( // something went wrong data.context.addClass("error"); ) )); $(document).on("drop dragover", function (e) ( e.preventDefault(); )); // helper function that formats the file size function formatFileSize(bytes) ( if (typeof bytes !== "number") ( return ""; ) if (bytes >= 1000000000) ( return (bytes / 1000000000).toFixed(2 ) + "GB"; ) if (bytes >= 1000000) ( return (bytes / 1000000).toFixed(2) + " MB"; ) return (bytes / 1000).toFixed(2) + " KB"; ) ));

    jQuery File Upload has its own interface, but we use the basic version of the plugin to create our own interface design. And for our interface to work, we pass several parameters / callbacks to the plugin:

    • dropZone – This parameter contains a jQuery selector that will accept dropped files. Files dropped on it will be added to the download queue.
    • add – the function is called when a file is added to the download queue. It will generate markup for the files and call the data.submit() method.
    • progress – This function will be called every 100ms (can be changed). The second argument contains the file size and the number of bytes downloaded. This allows you to track progress and update the scale.
    • fail – the function is called when an error occurs.
    PHP

    jQuery File Upload also includes PHP script to process files on the server, but we will write our own. The process of downloading files will occur in the same way as during a normal download, so we can get all the information about them from the global $_FILES array: