Prerequisites
- Web Methods in ASP.NET
- JavaScript
- jQuery
- jQuery UI
- Ajax using jQuery
- HTML
Here I have implemented drag and drop file uploads using jQuery, Ajax, Web Methods and a Web Handler. For a better understanding I have divided the article into the following 5 parts:
- HTML
- Use of jQuery-UI
- WebHandler
- WebMethod
- Registering the Events for Drag N Drop in JavaScript
1. HTML
Here I have used div#dropzone as a container in which I will be dropping all the images that I want to upload.
The div#MSG acts like a popup that is used to denote that the file is being uploaded. By default it is hidden and only shows the file being uploaded.
The div#MSG acts like a popup that is used to denote that the file is being uploaded. By default it is hidden and only shows the file being uploaded.
- <div id="MSG">
- <img src="loading.gif" alt="Uploading File" />
- </div>
- <div id="dropzone">
- </div>
The jQuery-UI contains the function sortable that helps in sorting the file by dragging them to the position where you want them to be.
The function disableSelection disables any kind of select, actually it is not required in this scenario but it is a good practice to do so. In a scenario where you want to drag and drop some text you may find that the browser gets confused with the selection of text with the dragging of text.
Note: The sortable() function doesn't make the div#dropzone sortable, but the child elements in it.
- $("#dropzone").sortable();
- $("#dropzone").disableSelection();
Here I am using a WebHandler to upload files, basically the handlers does the heavy lifting.The WebHandler has a function called ProcessRequest, actually It is not exactly a part of the web handler but is overridden as the handler implements the IHttpHandler Interface. The function ProcessRequest has a parameter of type HttpContext, the object of class HttpContext provides a reference to the intrinsic server objects like Request, Response, Session and Server available with the HTTP Request. In the code below you will find that I have used a GUID to generate a Unique ID and concatenating it with the file name so that in any case the user tries to upload images with the same file name then it should not be overwritten. Once the files are saved the method sends a responseText to the client. I have used it to denote the status of the update by text "Success", if successful, else I am sending the error message in the responseText since I will use it to confirm the upload on the page.
4. WebMethod
- public void ProcessRequest(HttpContext context)
- {
- try
- {
- if (context.Request.Files.Count > 0) //Compare File Count
- {
- string FileName = "";
- HttpFileCollection files = context.Request.Files;
- for (int i = 0; i < files.Count; i++)
- {
- HttpPostedFile file = files[i];
- Guid id = Guid.NewGuid();
- FileName = id + "__" + file.FileName;
- string fName = context.Server.MapPath("Images/" + FileName);
- file.SaveAs(fName);
- }
- context.Response.ContentType = "text/plain";
- context.Response.Write("Success");
- }
- }
- catch (Exception ex)
- {
- context.Response.ContentType = "text/plain";
- context.Response.Write(ex.Message);
- }
- }
Here I have made 2 Web Methods called GetFileList and DeleteImage. By declaring the function as a WebMethod we are exposing the server-side function such that the method can be called from a remote web client.
- [WebMethod]
- public static string GetFileList()
- {
- //This function is used to collect list of Files Names from the Images folder.
- //This function returns the data in JSON format
- //I am using a function called ConvertDataTabletoString to serialize a Datatable into a JSON String
- CommonFunction com = new CommonFunction();
- string[] filePaths = Directory.GetFiles(HttpContext.Current.Server.MapPath("Images/"));
- DataTable dt = new DataTable();
- dt.Columns.Add("File");
- foreach (string file in filePaths)
- {
- dt.Rows.Add(Path.GetFileName(file));
- }
- return com.ConvertDataTabletoString(dt);
- }
- [WebMethod]
- public static string DeleteImage(string fileName)
- {
- //This function is used to delete a particular Image with the help of the FileName
- try
- {
- File.Delete(HttpContext.Current.Server.MapPath("Images/") + fileName);
- return "Success";
- }
- catch (Exception)
- {
- return "Failed";
- }
- }
Here is the best part of this article, register events to detect drag and drop. To do so the browser provides events like:
- ondragenter: Detects the dragged element's entry on the droppable target.
- ondragover: Detects the dragged element is over the droppable target.
- ondragleave: Detects the dragged element leaves the droppable target.
- ondrop: Detects the dragged element is dropped on the droppable target.
NOTE: the events are fired on droppable elements i.e div#dropzone and not on the draggable elements
- var dz = document.querySelector('#dropzone');
- dz.addEventListener('dragenter', handleDragEnter, false);//Register Event dragenter
- dz.addEventListener('dragover', handleDragOver, false);//Register Event dragover
- dz.addEventListener('dragleave', handleDragLeave, false);//Register Event dragleave
- dz.addEventListener('drop', handleDrop, false);//Register Event drop
Here I will use the function handleDrop() to handle the drop event. This function then uploads the dropped file to the server using jQuery Ajax on the Client-Side and WebHandler on the Server-Side. How I have implemented it, you can find it in the following code.
Complete Code
So here we have finished making a DROPZONE.
Complete Code
- $(document).ready(function () {
- var dz = document.querySelector('#dropzone');
- dz.addEventListener('dragenter', handleDragEnter, false);//Register Event dragenter
- dz.addEventListener('dragover', handleDragOver, false);//Register Event dragover
- dz.addEventListener('dragleave', handleDragLeave, false);//Register Event dragleave
- dz.addEventListener('drop', handleDrop, false);//Register Event drop
- GetFileDetails();// Load all The Images on PageLoad
- $("#dropzone").sortable();
- $("#dropzone").disableSelection();
- });
- function handleDragOver(e) {
- if (e.preventDefault) {
- e.preventDefault(); // Necessary. Allows us to drop.
- }
- this.classList.add('over');
- return false;
- }
- function handleDragEnter(e) {
- // If you have used the DropZone you must have noticed that when you drag an item into the browser the gray area(The DropZone)is hilighted by dotted line at its border
- // well here is how I do it I just add border to the div...
- // I Have created ta class called over which basically has the styles to hilight the div.
- // but only when the you are draging any file on the browser
- this.classList.add('over');
- }
- function handleDragLeave(e) {
- // while draging If you move the cursour out of the DropZone, then the hilighting must be removed
- // so here I am removing the class over from the div
- e.preventDefault();
- this.classList.remove('over');
- }
- //On Drop of file over the DropZone(I have Elaborated the process of What Happen on Drop in Points)
- function handleDrop(e) {
- //1st thing to do is Stop its default event, If you won't then the browser will end up rendering the file
- e.preventDefault();
- //2nd Checking if the the object e has any files in it.
- // actually the object named "dataTransfer" in the object e is the object that hold the data that is being dragged during a drag and drop operation
- // dataTransfer object can hold one or more files
- if (e.dataTransfer.files.length == 0) {
- this.classList.remove('over');
- return;// if no files are found then there is no point executing the rest of the code so I return to the function.
- }
- var files = e.dataTransfer.files;
- //3rd Here I am using an object of FormData() to send the files to the server using AJAX
- // The FormData object lets you compile a set of key/value pairs to send using AJAX
- // Its primarily intended for use in sending form data
- var data = new FormData();
- for (var i = 0, f; f = files[i]; i++) {
- data.append(files[i].name, files[i]);//Here I am appending the files from the dataTransfer object to FormData() object in Key(Name of File) Value(File) pair
- }
- // The operation of Uploading the file consumes time till the time the browser almost freezes
- this.classList.remove('over');
- //4th Once I have got all my files in the object of FormData() now I am ready to send the files to server to using AJAX
- var options = {};
- options.url = 'FileUploader.ashx';//URL
- options.type = 'post';//Post Method
- options.data = data;
- options.async = false;//synchronous Call
- options.contentType = false;
- options.processData = false;
- options.beforeSend = function () {
- ShowPopup();//POPUP used to show the uploading is under progress
- };
- options.error = function () {
- alert('Problem uploading file');
- HidePopup();
- };
- options.complete = function (response) {
- HidePopup();//Once the process is completed POPUP is removed
- GetFileDetails();//This function is used to bind the div#DropZone with images. I am calling it again to update the page with new Images
- };
- $.ajax(options);
- }
- var overlay = $('<div id="overlay"></div>');
- //By default the popup is hidden.
- //ShowPopup is used to show popup
- function ShowPopup() {
- //the body is appended with the the div#overlay which gives the dark background to the popup
- overlay.appendTo(document.body);
- $('#MSG').show();
- }
- //HidePopup is used to hide the popup
- function HidePopup() {
- $('#MSG').hide();
- overlay.appendTo(document.body).remove();
- }
- var imgControl = '<div class="imageControl">\
- <a href="javascript:deleteImage(\'||FILENAME||\');">\
- <img src="delete.png" />\
- </a>\
- <img src="Images/||FILENAME||" />\
- </div>';
- //GetFileDetails is used retrieve all the names of the file in the folder "Images"
- //It also renders the HTML with Images on the server
- //variable imgControl contains the HTML structure in which the Image is rendered.
- //Then using for loop, I Replace the text "||FILENAME||" with the actual Image File Name and finally Append it to the div#dropzone
- function GetFileDetails() {
- var options = {};
- options.type = "POST",//Post Method
- options.url = 'Default.aspx/GetFileList',//URL
- options.data = '{}',
- options.async = false,//synchronous Call
- options.contentType = "application/json; charset=utf-8",
- options.dataType = "json",
- options.complete = function (response) { //callback function on completion
- var resp = JSON.parse(response.responseText);
- var filesList = JSON.parse(resp.d);
- var imageControlList = '';
- for (var i = 0; i < filesList.length; i++) {
- imageControlList += imgControl.replace('||FILENAME||', filesList[i].File).replace('||FILENAME||', filesList[i].File);
- }
- $('#dropzone').html(imageControlList);
- };
- $.ajax(options);
- }
- //the function deleteImage is used to delete images
- function deleteImage(fileName) {
- var options = {};
- options.type = "POST",
- options.url = 'Default.aspx/DeleteImage',
- options.data = '{ fileName :"' + fileName + '" }',
- options.async = false,
- options.contentType = "application/json; charset=utf-8",
- options.dataType = "json",
- options.complete = function (response) {
- GetFileDetails();
- };
- $.ajax(options);
- }
Please do not forget to provide your valuable suggestions and feel free to ask queries.
That's all for this article, will see you in some other article. Until then, Keep Learning.

Akshay MistryPosted Apr 9, 2018, 4:06 AM
Could you help me to save this files on Button Click instead of drag & drop?
Sibeesh VenuPosted May 30, 2015, 1:15 PM
Good one.
Santhakumar MunuswamyPosted May 30, 2015, 12:39 PM
Thanks for sharing
NitinPosted May 30, 2015, 10:20 AM
Good one
Shailesh UkePosted May 30, 2015, 9:20 AM
Nice ...
Abhishek JaiswalPosted May 29, 2015, 11:28 AM
Good one. Keep sharing!! :)
Dominique CejaPosted May 29, 2015, 10:41 AM
Superb.
Gaurav TyagiPosted May 29, 2015, 8:29 AM
very impressive