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:
  1. HTML
  2. Use of jQuery-UI
  3. WebHandler
  4. WebMethod
  5. 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.
  1. <div id="MSG">
  2. <img src="loading.gif" alt="Uploading File" />
  3. </div>
  4. <div id="dropzone">
  5. </div>
2. Use of jQuery-UI
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.
  1. $("#dropzone").sortable();
  2. $("#dropzone").disableSelection();
3. WebHandler
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.
  1. public void ProcessRequest(HttpContext context)
  2. {
  3. try
  4. {
  5. if (context.Request.Files.Count > 0) //Compare File Count
  6. {
  7. string FileName = "";
  8. HttpFileCollection files = context.Request.Files;
  9. for (int i = 0; i < files.Count; i++)
  10. {
  11. HttpPostedFile file = files[i];
  12. Guid id = Guid.NewGuid();
  13. FileName = id + "__" + file.FileName;
  14. string fName = context.Server.MapPath("Images/" + FileName);
  15. file.SaveAs(fName);
  16. }
  17. context.Response.ContentType = "text/plain";
  18. context.Response.Write("Success");
  19. }
  20. }
  21. catch (Exception ex)
  22. {
  23. context.Response.ContentType = "text/plain";
  24. context.Response.Write(ex.Message);
  25. }
  26. }
4. WebMethod
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.
  1. [WebMethod]
  2. public static string GetFileList()
  3. {
  4. //This function is used to collect list of Files Names from the Images folder.
  5. //This function returns the data in JSON format
  6. //I am using a function called ConvertDataTabletoString to serialize a Datatable into a JSON String
  7. CommonFunction com = new CommonFunction();
  8. string[] filePaths = Directory.GetFiles(HttpContext.Current.Server.MapPath("Images/"));
  9. DataTable dt = new DataTable();
  10. dt.Columns.Add("File");
  11. foreach (string file in filePaths)
  12. {
  13. dt.Rows.Add(Path.GetFileName(file));
  14. }
  15. return com.ConvertDataTabletoString(dt);
  16. }
  17. [WebMethod]
  18. public static string DeleteImage(string fileName)
  19. {
  20. //This function is used to delete a particular Image with the help of the FileName
  21. try
  22. {
  23. File.Delete(HttpContext.Current.Server.MapPath("Images/") + fileName);
  24. return "Success";
  25. }
  26. catch (Exception)
  27. {
  28. return "Failed";
  29. }
  30. }
5. Registering the Events for Drag N Drop in JavaScript
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
  1. var dz = document.querySelector('#dropzone');
  2. dz.addEventListener('dragenter', handleDragEnter, false);//Register Event dragenter
  3. dz.addEventListener('dragover', handleDragOver, false);//Register Event dragover
  4. dz.addEventListener('dragleave', handleDragLeave, false);//Register Event dragleave
  5. 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
  1. $(document).ready(function () {
  2. var dz = document.querySelector('#dropzone');
  3. dz.addEventListener('dragenter', handleDragEnter, false);//Register Event dragenter
  4. dz.addEventListener('dragover', handleDragOver, false);//Register Event dragover
  5. dz.addEventListener('dragleave', handleDragLeave, false);//Register Event dragleave
  6. dz.addEventListener('drop', handleDrop, false);//Register Event drop
  7. GetFileDetails();// Load all The Images on PageLoad
  8. $("#dropzone").sortable();
  9. $("#dropzone").disableSelection();
  10. });
  11. function handleDragOver(e) {
  12. if (e.preventDefault) {
  13. e.preventDefault(); // Necessary. Allows us to drop.
  14. }
  15. this.classList.add('over');
  16. return false;
  17. }
  18. function handleDragEnter(e) {
  19. // 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
  20. // well here is how I do it I just add border to the div...
  21. // I Have created ta class called over which basically has the styles to hilight the div.
  22. // but only when the you are draging any file on the browser
  23. this.classList.add('over');
  24. }
  25. function handleDragLeave(e) {
  26. // while draging If you move the cursour out of the DropZone, then the hilighting must be removed
  27. // so here I am removing the class over from the div
  28. e.preventDefault();
  29. this.classList.remove('over');
  30. }
  31. //On Drop of file over the DropZone(I have Elaborated the process of What Happen on Drop in Points)
  32. function handleDrop(e) {
  33. //1st thing to do is Stop its default event, If you won't then the browser will end up rendering the file
  34. e.preventDefault();
  35. //2nd Checking if the the object e has any files in it.
  36. // 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
  37. // dataTransfer object can hold one or more files
  38. if (e.dataTransfer.files.length == 0) {
  39. this.classList.remove('over');
  40. return;// if no files are found then there is no point executing the rest of the code so I return to the function.
  41. }
  42. var files = e.dataTransfer.files;
  43. //3rd Here I am using an object of FormData() to send the files to the server using AJAX
  44. // The FormData object lets you compile a set of key/value pairs to send using AJAX
  45. // Its primarily intended for use in sending form data
  46. var data = new FormData();
  47. for (var i = 0, f; f = files[i]; i++) {
  48. 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
  49. }
  50. // The operation of Uploading the file consumes time till the time the browser almost freezes
  51. this.classList.remove('over');
  52. //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
  53. var options = {};
  54. options.url = 'FileUploader.ashx';//URL
  55. options.type = 'post';//Post Method
  56. options.data = data;
  57. options.async = false;//synchronous Call
  58. options.contentType = false;
  59. options.processData = false;
  60. options.beforeSend = function () {
  61. ShowPopup();//POPUP used to show the uploading is under progress
  62. };
  63. options.error = function () {
  64. alert('Problem uploading file');
  65. HidePopup();
  66. };
  67. options.complete = function (response) {
  68. HidePopup();//Once the process is completed POPUP is removed
  69. GetFileDetails();//This function is used to bind the div#DropZone with images. I am calling it again to update the page with new Images
  70. };
  71. $.ajax(options);
  72. }
  73. var overlay = $('<div id="overlay"></div>');
  74. //By default the popup is hidden.
  75. //ShowPopup is used to show popup
  76. function ShowPopup() {
  77. //the body is appended with the the div#overlay which gives the dark background to the popup
  78. overlay.appendTo(document.body);
  79. $('#MSG').show();
  80. }
  81. //HidePopup is used to hide the popup
  82. function HidePopup() {
  83. $('#MSG').hide();
  84. overlay.appendTo(document.body).remove();
  85. }
  86. var imgControl = '<div class="imageControl">\
  87. <a href="javascript:deleteImage(\'||FILENAME||\');">\
  88. <img src="delete.png" />\
  89. </a>\
  90. <img src="Images/||FILENAME||" />\
  91. </div>';
  92. //GetFileDetails is used retrieve all the names of the file in the folder "Images"
  93. //It also renders the HTML with Images on the server
  94. //variable imgControl contains the HTML structure in which the Image is rendered.
  95. //Then using for loop, I Replace the text "||FILENAME||" with the actual Image File Name and finally Append it to the div#dropzone
  96. function GetFileDetails() {
  97. var options = {};
  98. options.type = "POST",//Post Method
  99. options.url = 'Default.aspx/GetFileList',//URL
  100. options.data = '{}',
  101. options.async = false,//synchronous Call
  102. options.contentType = "application/json; charset=utf-8",
  103. options.dataType = "json",
  104. options.complete = function (response) { //callback function on completion
  105. var resp = JSON.parse(response.responseText);
  106. var filesList = JSON.parse(resp.d);
  107. var imageControlList = '';
  108. for (var i = 0; i < filesList.length; i++) {
  109. imageControlList += imgControl.replace('||FILENAME||', filesList[i].File).replace('||FILENAME||', filesList[i].File);
  110. }
  111. $('#dropzone').html(imageControlList);
  112. };
  113. $.ajax(options);
  114. }
  115. //the function deleteImage is used to delete images
  116. function deleteImage(fileName) {
  117. var options = {};
  118. options.type = "POST",
  119. options.url = 'Default.aspx/DeleteImage',
  120. options.data = '{ fileName :"' + fileName + '" }',
  121. options.async = false,
  122. options.contentType = "application/json; charset=utf-8",
  123. options.dataType = "json",
  124. options.complete = function (response) {
  125. GetFileDetails();
  126. };
  127. $.ajax(options);
  128. }
So here we have finished making a DROPZONE.

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.