Uploading folders is extremely useful when users are allowed to upload large amounts of files. This topic describes how to enable this feature in HTML5 Uploader and restore the folder structure on the server.
To turn the folder uploading on in the HTML5 Uploader, just set the imageUploaderFlash.folderProcessingMode property to one of the following values:
Note, that you can use the values accepted by Java/ActiveX uploader as well for compatibility.
HTML5 Uploader supports folder uploads only in Chrome. If you want to use it with other browsers as well, it is recommended to use both Java/ActiveX and HTML5/Flash uploaders together as discussed below.
When you turn this feature on, it affects not only the open file/folder dialog, but also drag-and-drop functionality. All its subfolders become selected recursively.
There is a limitation in Google Chrome for a number of files added when you drop a folder - it adds not more than 100 files per a folder. This limitation is not applied if the user adds a folder using a dialog. There is no official information from Google regarding this issue, so it is probably happens only on particular versions.
Here is an example how to use the folderProcessingMode property:
var u = $au.imageUploaderFlash({ id: 'Uploader1', // other params folderProcessingMode: 'Mixed' });
In this case, if a user selects a folder, all the files in this folder will be recursively added to the upload pane (except of ones filtered due to the restrictions); so a user can
clearly see all the files selected at once. When a user starts the upload, the HTML5 Uploader sends the folder structure information (i.e. relative paths) along with file names.
For instance, if a user sends a MyDocuments
folder, which contains a MyPhotos
subfolder, all
files inside this subfolder will be sent to a server along with MyDocuments\MyPhotos\filename
relative paths and
all files contained directly in the MyDocuments
folder will have MyDocuments\filename
relative paths.
If you need to access the folder structure of a selected file before the upload, from your JavaScript code, you can use
It is impossible to get the uploader to send absolute paths.
As stated in the previous section, when the folder is uploaded, the SourceName_i POST field will contain not only the filename but also a relative path to the ith file. So, if you want to restore folders structure on the server, you should parse the SourceName_i field and recreate a path to the ith file, folder by folder. The following algorithm describes this idea more detailed:
Iterate through all files uploaded in the current package (their total number is contained in the PackageFileCount field).
In this loop:
Here is a pseudocode for this algorithm:
//The folder to save uploaded folders to string catalogPath iterate through each file (i) { // Check if it is POST request if not (RequestMethod is POST) exit(); //Take the value from the SourceName_i POST field string relativePath = POST["SourceName_" + i] //The 'split' function splits a string into an array of substrings using //the specified delimiter ('\' in our case) array folderStructure = split(relativePath, "\") //The 'count' function returns number of elements in array integer folderCount = count(folderStructure) //This value containes only the name of received file string fileName = folderStructure[folderCount] //The 'goToFolder' function changes the current working folder to the specified one goToFolder(catalogPath) //iterate through all but last one folder names iterate through folderCount-1 elements of folderStructure (j) { //The 'exists' function checks if the specified folder exists under the current location if not exists(folderStructure[j]) { //The 'createFolder' function creates a subfolder createFolder(folderStructure[j]) } goToFolder(folderStructure[j]) } //The 'save' function saves the i-th file in the current working folder with the fileName name save(file[i], fileName) }
You may find it annoying that the folder uploading functionality is supported only by Google. To be able to upload folders from other browsers than Chrome, you have to use Java/ActivX uploader there. Here is the example how to do it:
<!DOCTYPE html> <html> <head> <title>Uploading folders in any browser</title> <link rel="stylesheet" type="text/css" href="../../aurigma/last/fh/css/aurigma.htmluploader.control.css" /> <script src="../../aurigma/last/fh/aurigma.imageuploaderflash.js"></script> <script src="../../aurigma/last/fh/aurigma.htmluploader.control.js"></script> <script src="../../aurigma/last/aj/aurigma.uploader.js"></script> </head> <body> <script type="text/javascript"> // Browser detection method is found at // http://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser var isChrome = !!window.chrome && navigator.userAgent.indexOf(' OPR/') < 0; var uploader; if (isChrome) { uploader = Aurigma.ImageUploaderFlash.imageUploaderFlash({ id: "aurigma-fh1" // insert HTML5/Flash-specific params here }); } else { uploader = Aurigma.ImageUploader.uploader({ id: "aurigma-aj1", activeXControl: { codeBase: "../../aurigma/last/aj/Uploader8.cab", codeBase64: "../../aurigma/last/aj/Uploader8_x64.cab"}, javaControl: {codeBase: "../../aurigma/last/aj/Uploader8.jar"}, folderPane: { viewMode: 'Details' }, uploadSettings: { filesPerPackage: 1 }, detailsViewColumns: { dimensionsText: '', infoText: '' } // insert Java/ActivX-specific params here }); } uploader.set({ folderProcessingMode: 'Mixed', uploadPane: { viewMode: 'Tiles' }, converters: [{ mode: "*.*=SourceFile" }], uploadSettings: { actionUrl: '/destination_url', redirectUrl: '/redirect_url' } }); uploader.writeHtml(); </script> </body> </html>
The same server file processing code should work fine with both uploaders.