In this example, the Uploader is used to send multiple images or videos to the server and monitor their upload progress with individual counters.
Please note: This example will not work when run from a local filesystem because of security restrictions in the transport protocols used. If you’d like to run this example locally, set up a local web server and launch it from there.
Also note: You will need compile and host your own flashuploader.swf
file to enable Flash mode which is needed for IE <= 9. Necessary source files are available in the yui3-swfs repository.
Also note: The uploader is not supported on iOS devices (iPhone and iPad), because they lack file upload capability. This example provides a graceful degradation message for all such systems.
Also note: The backend script used in these examples does not store any information it receives. Nevertheless, do not submit any sensitive or private data and keep your tests to a few small files to avoid overloading the system.
File name | File size | Percent uploaded |
---|---|---|
No files have been selected. |
In this example, the UI for the Uploader consists of two buttons, a label field for displaying the uploader type and the overall upload progress, as well as a table for displaying information about the upload process per file. We first create the markup for the UI:
<div id="uploaderContainer"> <div id="selectFilesButtonContainer"> </div> <div id="uploadFilesButtonContainer"> <button type="button" id="uploadFilesButton" class="yui3-button" style="width:250px; height:35px;">Upload Files</button> </div> <div id="overallProgress"> </div> <div id="filelist"> <table id="filenames"> <thead> <tr><th>File name</th><th>File size</th><th>Percent uploaded</th></tr> <tr id="nofiles"> <td colspan="3"> No files have been selected. </td> </tr> </thead> <tbody> </tbody> </table> </div>
Next, we create, configure and render an instance of the Uploader. Note that we initially check that the Y.Uploader.TYPE
property is
not set to 'none' and that we are not trying to run the code on an iOS device (where file uploads are not allowed because of a closed file system).
Also note that we are setting a fixed width and height on the uploader, which is necessary in order for the Flash overlay to render correctly
in browsers where Flash is used:
if (Y.Uploader.TYPE != "none" && !Y.UA.ios) { var uploader = new Y.Uploader({width: "250px", height: "35px", multipleFiles: true, swfURL: "flashuploader.swf?t=" + Math.random(), uploadURL: "http://yuilibrary.com/sandbox/upload/", simLimit: 2, withCredentials: false }); var uploadDone = false; uploader.render("#selectFilesButtonContainer"); ...
We can now add handlers for various uploader events. The first handler is for the fileselect
event. In it, we retrieve the list of
files selected by the user and populate the table with their names, sizes and a field for reporting the percentage uploaded for each
file. The id of each row in the table is prefixed with the unique file id it is associated with, for easy reference later:
uploader.after("fileselect", function (event) { var fileList = event.fileList; var fileTable = Y.one("#filenames tbody"); if (fileList.length > 0 && Y.one("#nofiles")) { Y.one("#nofiles").remove(); if (uploadDone) { uploadDone = false; fileTable.setHTML(""); } Y.each(fileList, function (fileInstance) { fileTable.append("<tr id='" + fileInstance.get("id") + "_row" + "'>" + "<td class='filename'>" + fileInstance.get("name") + "</td>" + "<td class='filesize'>" + fileInstance.get("size") + "</td>" + "<td class='percentdone'>Hasn't started yet</td>"); }); });
For the uploadprogress
event, we update the individual file row (using the unique file id prefix to reference each row) with the
percentLoaded
property from the event payload.
uploader.on("uploadprogress", function (event) { var fileRow = Y.one("#" + event.file.get("id") + "_row"); fileRow.one(".percentdone").set("text", event.percentLoaded + "%"); });
When the upload starts, we disable the uploader and the Upload Files
button until the upload process is complete:
uploader.on("uploadstart", function (event) { uploader.set("enabled", false); Y.one("#uploadFilesButton").addClass("yui3-button-disabled"); Y.one("#uploadFilesButton").detach("click"); });
When each individual file upload completes, we update the table row corresponding with the file with the appropriate message:
uploader.on("uploadcomplete", function (event) { var fileRow = Y.one("#" + event.file.get("id") + "_row"); fileRow.one(".percentdone").set("text", "Finished!"); });
On totaluploadprogress
events, we report the overall upload progress in the top-right message container:
uploader.on("totaluploadprogress", function (event) { Y.one("#overallProgress").setHTML("Total uploaded: <strong>" + event.percentLoaded + "%" + "</strong>"); });
We can listen for the alluploadscomplete
event to find out when all uploads have completed, re-enable the uploader and report that information accordingly:
uploader.on("alluploadscomplete", function (event) { uploader.set("enabled", true); uploader.set("fileList", []); Y.one("#uploadFilesButton").removeClass("yui3-button-disabled"); Y.one("#uploadFilesButton").on("click", function () { if (!uploadDone && uploader.get("fileList").length > 0) { console.log(uploader.get("fileList").length); uploader.uploadAll(); }); Y.one("#overallProgress").set("text", "Uploads complete!"); uploadDone = true; });
Finally, we add the click
event listener to the "Upload Files" button to start the file upload process:
Y.one("#uploadFilesButton").on("click", function () { if (!uploadDone && uploader.get("fileList").length > 0) { console.log(uploader.get("fileList").length); uploader.uploadAll(); } });
<style> #filelist { margin-top: 15px; } #uploadFilesButtonContainer, #selectFilesButtonContainer, #overallProgress { display: inline-block; } #overallProgress { float: right; } </style> <div id="uploaderContainer"> <div id="selectFilesButtonContainer"> </div> <div id="uploadFilesButtonContainer"> <button type="button" id="uploadFilesButton" class="yui3-button" style="width:250px; height:35px;">Upload Files</button> </div> <div id="overallProgress"> </div> </div> <div id="filelist"> <table id="filenames"> <thead> <tr><th>File name</th><th>File size</th><th>Percent uploaded</th></tr> <tr id="nofiles"> <td colspan="3"> No files have been selected. </td> </tr> </thead> <tbody> </tbody> </table> </div> <script> YUI({filter:"raw"}).use("uploader", function(Y) { Y.one("#overallProgress").set("text", "Uploader type: " + Y.Uploader.TYPE); if (Y.Uploader.TYPE != "none" && !Y.UA.ios) { var uploader = new Y.Uploader({width: "250px", height: "35px", multipleFiles: true, swfURL: "flashuploader.swf?t=" + Math.random(), uploadURL: "http://yuilibrary.com/sandbox/upload/", simLimit: 2, withCredentials: false }); var uploadDone = false; uploader.render("#selectFilesButtonContainer"); uploader.after("fileselect", function (event) { var fileList = event.fileList; var fileTable = Y.one("#filenames tbody"); if (fileList.length > 0 && Y.one("#nofiles")) { Y.one("#nofiles").remove(); } if (uploadDone) { uploadDone = false; fileTable.setHTML(""); } Y.each(fileList, function (fileInstance) { fileTable.append("<tr id='" + fileInstance.get("id") + "_row" + "'>" + "<td class='filename'>" + fileInstance.get("name") + "</td>" + "<td class='filesize'>" + fileInstance.get("size") + "</td>" + "<td class='percentdone'>Hasn't started yet</td>"); }); }); uploader.on("uploadprogress", function (event) { var fileRow = Y.one("#" + event.file.get("id") + "_row"); fileRow.one(".percentdone").set("text", event.percentLoaded + "%"); }); uploader.on("uploadstart", function (event) { uploader.set("enabled", false); Y.one("#uploadFilesButton").addClass("yui3-button-disabled"); Y.one("#uploadFilesButton").detach("click"); }); uploader.on("uploadcomplete", function (event) { var fileRow = Y.one("#" + event.file.get("id") + "_row"); fileRow.one(".percentdone").set("text", "Finished!"); }); uploader.on("totaluploadprogress", function (event) { Y.one("#overallProgress").setHTML("Total uploaded: <strong>" + event.percentLoaded + "%" + "</strong>"); }); uploader.on("alluploadscomplete", function (event) { uploader.set("enabled", true); uploader.set("fileList", []); Y.one("#uploadFilesButton").removeClass("yui3-button-disabled"); Y.one("#uploadFilesButton").on("click", function () { if (!uploadDone && uploader.get("fileList").length > 0) { uploader.uploadAll(); } }); Y.one("#overallProgress").set("text", "Uploads complete!"); uploadDone = true; }); Y.one("#uploadFilesButton").on("click", function () { if (!uploadDone && uploader.get("fileList").length > 0) { uploader.uploadAll(); } }); } else { Y.one("#uploaderContainer").set("text", "We are sorry, but to use the uploader, you either need a browser that support HTML5 or have the Flash player installed on your computer."); } }); </script>