Click here to Skip to main content
15,880,608 members
Articles / Web Development / ASP.NET

Folder Tree with Multiple File Upload with Progress Bar and Drag and Drop

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
19 Feb 2019CPOL1 min read 8.7K   338   7   1
The ASP.NET pages let you upload, delete and browse files in a folder.

Introduction

This ASP.NET application will let you upload multiple files manually or via drag and drop. It will show progress bar for each file as it uploads. A zip file can be extracted after the upload. Once uploaded, you can browse and delete these files and folders.

Image 1

Background

This is a sequel to my earlier article, Multiple file upload with progress bar and drag and drop. This version adds the following features:

  • Ability to browse and expand folders
  • Ability to zip and download all files
  • Ability to upload and extract a zip file - this lets you create folders on the server
  • Ability to search and sort files in the browser

This project uses:

To use this application:

  1. Download Upload3.zip and unzip it to C:\inetpub\wwwroot\Upload.
  2. Give everyone (or the IIS anonymous user) access to C:\inetpub\wwwroot\Upload\upload folderBr>

    Image 2

  3. In IIS Manager, right click Upload folder and convert it to Application.

    Image 3

  4. Point your browser to http://localhost/Upload/Upload.aspx?folder=upload.
  5. You can change URL from ?folder=upload to your folder like: folder=folder1 if you want to point the page to folder1.

Here is the code for Upload.js:

JavaScript
var iFiles = 0;
var iDoneFiles = 0;
var iFolderId = 0;
var oTable = null;
var bTableDirty = false;

function OnLoad() {

    _("file1").addEventListener("change", FileSelectHandler, false);

    var xhr = new XMLHttpRequest();
    if (xhr.upload) {
        
        var filedrag = _("divDropHere");
        if (filedrag){
            filedrag.addEventListener("dragover", FileDragHover, false);
            filedrag.addEventListener("dragleave", FileDragHover, false);
            filedrag.addEventListener("drop", FileSelectHandler, false);
            filedrag.style.display = "block";
        }

        _("btnUpload").style.display = "none";
    }

    SetupDataTable();
    SetupDeleteBtn();
}

function SetupDataTable() {
    var h = $(window).height() - 310;
    oTable = $('#tbServer').DataTable({
        scrollY: h,
        scrollCollapse: false,
        paging: false,
        searching: true,
        ordering: true,
        order: [],
        "scrollX": true,
        info: false
    });

    $('.dataTables_scrollHeadInner').mousedown(function (e) {
        CleanDirtyTable()
    });

    $("input[type='search']").focus(function () {
        CleanDirtyTable();
        $("input[type='search']").focus();
    })
}

function CleanDirtyTable() {
    if (bTableDirty) {
        ResetDataTable();
        SetupDeleteBtn();
        bTableDirty = false;
    }
}

function Delete() {
    if (confirm("Delete?")) {
        form1.hdnAction.value = "Delete";
        form1.submit();
    }
}

function DownloadAll() {
    if (confirm("Download all as one zip file?")) {
        form1.hdnAction.value = "DownloadAll";
        form1.submit();
    }
}

function SetupDeleteBtn() {
    $("input[name='chkDelete'],input[name='chkDeleteFolder'],input[name='chkDeleteAll']").click(function () {
        $("#btnDelete").show("slow");
    })
}

function FileDragHover(e) {
    e.stopPropagation();
    e.preventDefault();
    e.target.className = (e.type=="dragover")?"hover":"";
}

function FileSelectHandler(e) {
    FileDragHover(e);

    var oFiles = e.target.files || e.dataTransfer.files;
    if (oFiles.length == 0) return;

    var sHtml = "";

    for (var i = 0; i < oFiles.length; i++) {
        var iSize = oFiles[i].size;
        var sName = oFiles[i].name;
        sHtml += "<tr><td>" + sName + "</td>"
                   + "<td>" + (iSize / 1024).formatNumber(0, ',', '.') + " KB</td>"
                    + "<td id=progressBar" + i + "></td></tr>";
    }

    if (sHtml != "") {
        _("divStatus").innerHTML = "<table border=0 class='table table-striped'>" + sHtml + "</table>";
    }

    iFiles = oFiles.length;

    for (var i = 0; i < oFiles.length; i++) {
        UploadFile(oFiles[i], i);
    }
}

function UploadFile(file, i) {
    var xhr = new XMLHttpRequest();
    if (xhr.upload) {
        var progress = _("progressBar" + i).appendChild(document.createElement("div"));
        progress.className = "progressBar";
        progress.innerHTML = "&nbsp;";

        // progress bar
        xhr.upload.addEventListener("progress", function (e) {
            var pc = parseInt(100 - (e.loaded / e.total * 100));
            progress.style.backgroundPosition = pc + "% 0";
        }, false);

        // file received/failed
        xhr.onreadystatechange = function (e) {
            if (xhr.readyState == 4) {
                progress.className = "progressBar " + (xhr.status == 200 ? "progressSuccess" : "progressFailed");
                if (xhr.status == 200) {
                    iDoneFiles += 1;
                    if (iFiles == iDoneFiles) {
                        //upload done: refresh
                        location = location.href;
                        return;
                    }
                }
            }
        };

        var oFormData = new FormData();
        oFormData.append("myfile" + i, file);
        oFormData.append("chkUnzip", form1.chkUnzip.checked ? "1": "");
        xhr.open("POST", _("form1").action, true);
        xhr.send(oFormData);
    }
}

function DeleteAll(o){
    var oBoxes = document.getElementsByTagName("input");
    for (var i=1; i<oBoxes.length; i++){
        oBoxes[i].checked = o.checked;
    }
}

function _(id) {
    return document.getElementById(id);
}

Number.prototype.formatNumber = function(decPlaces, thouSeparator, decSeparator) {
    var n = this,
        decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
        decSeparator = decSeparator == undefined ? "." : decSeparator,
        thouSeparator = thouSeparator == undefined ? "," : thouSeparator,
        sign = n < 0 ? "-" : "",
        i = parseInt(n = Math.abs(+n || 0).toFixed(decPlaces)) + "",
        j = (j = i.length) > 3 ? j % 3 : 0;
    return sign + (j ? i.substr(0, j) + thouSeparator : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thouSeparator) + (decPlaces ? decSeparator + Math.abs(n - i).toFixed(decPlaces).slice(2) : "");
};

function ExpandFolder(o) {
    var tr = $(o).parent().parent();
    var oImg = tr.find("img.Plus");

    var id = tr.attr("data-folder-id");
    if (id + "" != "undefined") {
        

        if (oImg.attr("src").indexOf("plus.gif") != -1) {
            oImg.attr("src", "images/minus.gif");

            //expand files and folders
            var oChildren = tr.parent().find("tr[data-parent-id='" + id + "']");
            oChildren.show("fast");
        } else {            
            oImg.attr("src", "images/plus.gif");

            //collapse files, folders and subfolders
            var oChildren = tr.parent().find("tr.p" + id);
            oChildren.hide("fast");
            oChildren.find("img.Plus").attr("src", "images/plus.gif");
        }
        return;
    }

    var sFolder = tr.attr("data-folder");
    var iIndent = tr.attr("data-indent");
    iIndent = parseInt(iIndent) + 1;

    var sParentIds = tr.attr("data-parent-ids") || "";

    iFolderId += 1;
    tr.attr("data-folder-id", iFolderId);

    oImg.attr("src", "images/minus.gif");

    $.post("?subfolder=" + escape(sFolder) + "&indent=" + iIndent + "&folderId=" + iFolderId + "&parentIds=" + sParentIds, function (data) {
        $(tr).after(data);
        SetupDeleteBtn();
        if (oTable) oTable.columns.adjust();
        bTableDirty = true;
        //ResetDataTable();
    });

}

function ResetDataTable() {
    $("#tbServer thead tr").remove();
    var oHeadRow = $(".dataTables_scrollHeadInner").find("table thead tr").clone();
    $("#tbServer thead").append(oHeadRow);
    var oTbl = $("#tbServer").clone();
    oTable.destroy();
    $("#tbServer").remove();
    $("#divTbl").append(oTbl)
    SetupDataTable();
}

Here is the code for Upload.aspx.vb:

VB.NET
Public Class Upload
    Inherits System.Web.UI.Page

    Dim sFolder As String = "upload"

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Request.QueryString("folder") <> "" Then
            sFolder = Request.QueryString("folder")
        End If

        Dim sFolderPath As String = Server.MapPath(sFolder)
        If System.IO.Directory.Exists(sFolderPath) = False Then
            Response.Write("Folder does not exist: " & sFolderPath)
            Response.End()
        End If

        If Request.QueryString("subfolder") <> "" Then
            GetSubFolder(Request.QueryString("subfolder"), Request.QueryString("indent"), Request.QueryString("folderId"), Request.QueryString("parentIds"))
            Response.End()
        End If

        If Request.HttpMethod = "POST" Then

            If Request.Form("hdnAction") = "Delete" Then
                'Delete files
                If (Not Request.Form.GetValues("chkDelete") Is Nothing) Then
                    For i As Integer = 0 To Request.Form.GetValues("chkDelete").Length - 1
                        Dim sFileName As String = Request.Form.GetValues("chkDelete")(i)

                        Try
                            System.IO.File.Delete(sFolderPath & "\" & sFileName)
                        Catch ex As Exception
                            'Ignore error
                            Throw New Exception("Could not delete: " & sFolderPath & "\" & sFileName)
                        End Try
                    Next
                End If

                'Delete Folders
                If (Not Request.Form.GetValues("chkDeleteFolder") Is Nothing) Then
                    For i As Integer = 0 To Request.Form.GetValues("chkDeleteFolder").Length - 1
                        Dim sFolder As String = Request.Form.GetValues("chkDeleteFolder")(i)

                        Try
                            ClearFolder(sFolder)
                            System.IO.Directory.Delete(sFolder)
                        Catch ex As Exception
                            'Ignore error
                        End Try
                    Next
                End If

            ElseIf Request.Form("hdnAction") = "DownloadAll" Then
                DownloadAll(sFolderPath)

            Else
                'Upload Files
                For i As Integer = 0 To Request.Files.Count - 1
                    Dim oFile As System.Web.HttpPostedFile = Request.Files(i)
                    Dim sFileName As String = System.IO.Path.GetFileName(oFile.FileName)

                    If Request.Form("chkUnzip") <> "" AndAlso GetExtFromFileName(sFileName).ToLower() = "zip" Then
                        Dim sTempZipFilePath As String = sFolderPath & "\" & System.Guid.NewGuid().ToString("N") + ".zip"
                        oFile.SaveAs(sTempZipFilePath)
                        Dim oZip As New ICSharpCode.SharpZipLib.Zip.FastZip
                        oZip.ExtractZip(sTempZipFilePath, sFolderPath, Nothing)
                        System.IO.File.Delete(sTempZipFilePath)

                    Else
                        oFile.SaveAs(sFolderPath & "\" & sFileName)
                    End If

                Next
            End If

        End If

    End Sub

    Private Sub DownloadAll(ByVal sFolderPath As String)
        Dim oMemoryStream As New IO.MemoryStream()
        Dim oZipFile As ICSharpCode.SharpZipLib.Zip.ZipOutputStream = New ICSharpCode.SharpZipLib.Zip.ZipOutputStream(oMemoryStream)
        AddFilesToZip(oZipFile, sFolderPath, sFolderPath)
        oZipFile.Finish()

        Response.ContentType = "application/x-zip-compressed"
        Response.AddHeader("Content-Disposition", "attachment; filename=All.zip")
        Response.BinaryWrite(oMemoryStream.ToArray())

        oMemoryStream.Close()
        oZipFile.Close()
    End Sub

    Private oFilesInZip As New Hashtable

    Private Sub AddFilesToZip(ByRef oZipFile As ICSharpCode.SharpZipLib.Zip.ZipOutputStream, ByVal sFolderName As String, ByVal sBaseFolderName As String)
        Dim oFiles As String() = IO.Directory.GetFiles(sFolderName)
        For Each sFileName As String In oFiles
            Dim oFileInfo As New IO.FileInfo(sFileName)
            Dim entryName As String = sFileName.Replace(sBaseFolderName, "")
            AddFileToZip(oZipFile, sFileName, entryName)
        Next

        Dim oSubFolders As String() = IO.Directory.GetDirectories(sFolderName)
        For Each sSubFolderName As String In oSubFolders
            AddFilesToZip(oZipFile, sSubFolderName, sBaseFolderName)
        Next
    End Sub

    Private Sub AddFileToZip(ByRef oZipFile As ICSharpCode.SharpZipLib.Zip.ZipOutputStream, ByVal sFileName As String, ByVal sEntryName As String)
        sEntryName = ICSharpCode.SharpZipLib.Zip.ZipEntry.CleanName(sEntryName)

        'Exit If file already in zip
        If oFilesInZip.ContainsKey(sEntryName) Then
            Exit Sub
        Else
            oFilesInZip.Add(sEntryName, "1")
        End If

        Dim fi As New IO.FileInfo(sFileName)
        Dim newEntry As New ICSharpCode.SharpZipLib.Zip.ZipEntry(sEntryName)

        newEntry.DateTime = fi.LastWriteTime
        newEntry.Size = fi.Length

        oZipFile.PutNextEntry(newEntry)
        Dim buffer As Byte() = New Byte(4095) {}
        Using streamReader As IO.FileStream = IO.File.OpenRead(sFileName)
            ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(streamReader, oZipFile, buffer)
        End Using
        oZipFile.CloseEntry()
    End Sub

    Private Sub ClearFolder(ByVal FolderName As String)
        Dim dir As System.IO.DirectoryInfo = New System.IO.DirectoryInfo(FolderName)

        For Each fi As System.IO.FileInfo In dir.GetFiles()
            fi.IsReadOnly = False
            fi.Delete()
        Next

        For Each di As System.IO.DirectoryInfo In dir.GetDirectories()
            ClearFolder(di.FullName)
            di.Delete()
        Next
    End Sub

    Private Sub GetSubFolder(ByVal sSubFolderPath As String, ByVal iIndent As Integer, ByVal sFolderId As String, ByVal sParentIds As String)
        Dim sFolderIds As String = sFolderId
        If sParentIds <> "" Then
            sFolderIds = sParentIds & "," & sFolderId
        End If

        Dim sIndentCss As String = " style='padding-left:" & (iIndent * 15) & "px' "

        Dim sUploadFolderPath As String = Server.MapPath(sFolder)
        Dim sFolderPath As String = Server.MapPath(".")
        Dim sSubFolderName As String = Replace(Replace(sSubFolderPath, sFolderPath & "\", ""), "\", "/")
        Dim oFiles As String() = System.IO.Directory.GetFiles(sSubFolderPath)

        For i As Integer = 0 To oFiles.Length - 1
            Dim sFilePath As String = oFiles(i)
            Dim oFileInfo As New System.IO.FileInfo(sFilePath)
            Dim sFileName As String = oFileInfo.Name
            Dim sSize As String = FormatNumber((oFileInfo.Length / 1024), 0)
            If sSize = "0" AndAlso oFileInfo.Length > 0 Then sSize = "1"

            Dim sImg As String = GetFileImg(sFileName)

            Response.Write("<tr class='" & GetClassNameFromId(sFolderIds) & "' data-type='File' data-parent-id=""" & sFolderId & """ data-parent-ids=""" & sFolderIds & """>")
            Response.Write("<td" & sIndentCss & ">")
            'Response.Write("<span style='display:none'>" & sSubFolderPath & "</span>") ' for datatable sorting
            Response.Write("<span style='display:none'>File</span>")
            Response.Write("<img class='File' src='images/ext/" & sImg & "'> ")
            Response.Write("<a href=""" & sSubFolderName & "/" & sFileName & """ target='_blank'>" & sFileName + "</a></td>")
            Response.Write("<td>" & sSize & " KB</td>")
            Response.Write("<td>" & oFileInfo.LastWriteTime.ToShortDateString() & " " & oFileInfo.LastWriteTime.ToShortTimeString() & "</td>")
            Response.Write("<td><input type=checkbox name=chkDelete value=""" & Replace(sFilePath, sUploadFolderPath & "\", "") & """>")
            Response.Write("</tr>")
        Next

        Dim oFolders As String() = System.IO.Directory.GetDirectories(sSubFolderPath)
        For i As Integer = 0 To oFolders.Length - 1
            Dim sSubSubFolderPath As String = oFolders(i)
            Dim oFolderInfo As New IO.DirectoryInfo(sSubSubFolderPath)
            Response.Write("<tr  class='" & GetClassNameFromId(sFolderIds) & "' data-type='Folder' data-indent='" & iIndent & "' data-parent-id=""" & sFolderId & """ data-parent-ids=""" & sFolderIds & """ data-folder=""" & sSubSubFolderPath & """>")
            Response.Write("<td" & sIndentCss & ">")
            'Response.Write("<span style='display:none'>" & sSubSubFolderPath & "</span>") ' for datatable sorting
            Response.Write("<span style='display:none'>Folder</span>")
            Response.Write("<img src='images/plus.gif'class='Plus' onclick='ExpandFolder(this)'> ")
            Response.Write("<img class='Folder' src='images/folder_closed.gif' onclick='ExpandFolder(this)'> ")
            Response.Write("<span onclick='ExpandFolder(this)' class='FolderName'>" & oFolderInfo.Name + "</span></td>")
            Response.Write("<td></td>")
            Response.Write("<td>" & oFolderInfo.LastWriteTime.ToShortDateString() & " " & oFolderInfo.LastWriteTime.ToShortTimeString() & "</td>")
            Response.Write("<td><input type=checkbox name=chkDeleteFolder value=""" & sSubSubFolderPath & """>")
            Response.Write("</tr>")
        Next

    End Sub

    Function GetClassNameFromId(ByVal sFolderIds As String) As String
        Dim sRet As String = ""
        Dim oFolderIds As String() = sFolderIds.Split(",")
        For i As Integer = 0 To oFolderIds.Length - 1
            sRet += " p" & oFolderIds(i)
        Next

        Return Trim(sRet)
    End Function

    Public Sub ShowFiles()
        Dim sFolderPath As String = Server.MapPath(sFolder)
        Dim oFiles As String() = System.IO.Directory.GetFiles(sFolderPath)
        Dim oFolders As String() = System.IO.Directory.GetDirectories(sFolderPath)

        If oFiles.Length = 0 And oFolders.Length = 0 Then
            Exit Sub
        End If

        Response.Write("<table id='tbServer' class='table table-striped'>" & vbCrLf)
        Response.Write("<thead><tr>" & vbCrLf)
        Response.Write("<th>File name</th>")
        Response.Write("<th>Size</th>")
        Response.Write("<th>Date Modified</th>")
        Response.Write("<th><label><input type=checkbox name=chkDeleteAll onclick='DeleteAll(this)'> Delete</label></th></tr></thead><tbody>")

        For i As Integer = 0 To oFiles.Length - 1
            Dim sFilePath As String = oFiles(i)
            Dim oFileInfo As New System.IO.FileInfo(sFilePath)
            Dim sFileName As String = oFileInfo.Name
            Dim sSize As String = FormatNumber((oFileInfo.Length / 1024), 0)
            If sSize = "0" AndAlso oFileInfo.Length > 0 Then sSize = "1"

            Dim sImg As String = GetFileImg(sFileName)

            Response.Write("<tr data-type='File'>")
            Response.Write("<td><span style='display:none'>File</span><img class='File' src='images/ext/" & sImg & "'> ")
            Response.Write("<a href=""" & sFolder & "/" & sFileName & """ target='_blank'>" & sFileName + "</a></td>")
            Response.Write("<td>" & sSize & " KB</td>")
            Response.Write("<td>" & oFileInfo.LastWriteTime.ToShortDateString() & " " & oFileInfo.LastWriteTime.ToShortTimeString() & "</td>")
            Response.Write("<td><input type=checkbox name=chkDelete value=""" & sFileName & """>")
            Response.Write("</tr>")
        Next

        For i As Integer = 0 To oFolders.Length - 1
            Dim sSubFolderPath As String = oFolders(i)
            Dim oFolderInfo As New IO.DirectoryInfo(sSubFolderPath)
            Response.Write("<tr data-type='Folder' data-indent='0' data-folder=""" & sSubFolderPath & """>")
            Response.Write("<td>")
            'Response.Write("<span style='display:none'>" & sSubFolderPath & "</span>") ' for datatable sorting
            Response.Write("<span style='display:none'>Folder</span>")
            Response.Write("<img src='images/plus.gif'class='Plus' onclick='ExpandFolder(this)'> ")
            Response.Write("<img class='Folder' src='images/folder_closed.gif' onclick='ExpandFolder(this)'> ")
            Response.Write("<span onclick='ExpandFolder(this)' class='FolderName'>" & oFolderInfo.Name + "</span></td>")
            Response.Write("<td></td>")
            Response.Write("<td>" & oFolderInfo.LastWriteTime.ToShortDateString() & " " & oFolderInfo.LastWriteTime.ToShortTimeString() & "</td>")
            Response.Write("<td><input type=checkbox name=chkDeleteFolder value=""" & sSubFolderPath & """>")
            Response.Write("</tr>")
        Next

        Response.Write("</tbody></table>")
    End Sub

    Private Function GetFileImg(sFileName As String) As String
        Dim sFileExt As String = GetExtFromFileName(sFileName)
        Return GetFileExtImg(sFileExt)
    End Function

    Private Function GetFileExtImg(sFileExt As String) As String
        Select Case LCase(Trim(sFileExt))
            Case "bmp" : Return "bmp.gif"
            Case "tif", "tiff" : Return "tif.png"
            Case "doc", "rtf" : Return "doc.gif"
            Case "exe", "bat" : Return "exe.gif"
            Case "gif", "jpg", "png" : Return "gif.gif"
            Case "htm", "tml" : Return "htm.gif"
            Case "mdb" : Return "mdb.gif"
            Case "mp3", "mpg", "avi", "mid" : Return "mp3.gif"
            Case "mpp" : Return "mpp.gif"
            Case "pdf" : Return "pdf.gif"
            Case "ppt" : Return "ppt.gif"
            Case "rpt" : Return "rpt.gif"
            Case "txt" : Return "txt.gif"
            Case "xls", "csv", "lsx" : Return "xls.gif"
            Case "xml" : Return "xml.gif"
            Case "zip", "cab" : Return "zip.gif"
            Case "eml" : Return "eml.gif"
            Case "swf" : Return "swf.gif"
            Case "vsd" : Return "vsd.gif"
            Case "xlt" : Return "xlt.gif"

            Case "xls", "xlsx" : Return "xls.gif"
            Case "doc", "docx" : Return "doc.gif"
            Case "ppt", "pptx" : Return "ppt.gif"

            Case "msg" : Return "ml.gif"

            Case Else : Return "all.gif"
        End Select
    End Function

    Private Function GetExtFromFileName(ByVal s As String) As String
        If s = "" Then
            Return ""
        End If

        Dim iPos As Integer = s.LastIndexOf(".")
        If iPos = -1 Then
            Return ""
        End If

        Return s.Substring(iPos + 1)
    End Function

End Class

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Igor is a business intelligence consultant working in Tampa, Florida. He has a BS in Finance from University of South Carolina and Masters in Information Management System from University of South Florida. He also has following professional certifications: MCSD, MCDBA, MCAD.

Comments and Discussions

 
QuestionHow to add in sub folder at the time of upload Pin
Member 1485588626-May-21 17:17
Member 1485588626-May-21 17:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.