uploader-multiple.mustache revision 76438e9b6959cc0bd7e35fb9cf5a11c87a37f744
<div class="intro">
<p>In this example, the Uploader is used to send multiple images or videos to the server and monitor
their upload progress with individual counters.</p>
<p><strong>Please note:</strong> 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.</p>
<p><strong>Also note:</strong> 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.</p>
<p><strong>Also note:</strong> 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.</p>
</div>
<div class="example yui3-skin-sam">
{{>uploader-multiple-source}}
</div>
<h2>Setting up Uploader UI</h2>
<p>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:</p>
```
<div id="uploaderContainer">
<div id="selectFilesButtonContainer">
</div>
<div id="uploadFilesButtonContainer">
<button type="button" id="uploadFilesButton"
class="yui3-button" style="width:250px; height:25px;">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>
```
<p>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:
</p>
```
if (Y.Uploader.TYPE != "none" && !Y.UA.ios) {
var uploader = new Y.Uploader({width: "250px",
height: "25px",
multipleFiles: true,
swfURL: "../build/uploader/assets/flashuploader.swf?t=" + Math.random(),
uploadURL: "http://www.yswfblog.com/upload/simpleupload.php",
simLimit: 2
});
var uploadDone = false;
uploader.render("#selectFilesButtonContainer");
...
```
<h2>Adding Uploader Event Handlers</h2>
<p>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:</p>
```
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.setContent("");
}
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>");
});
});
```
<p>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.</p>
```
uploader.on("uploadprogress", function (event) {
var fileRow = Y.one("#" + event.file.get("id") + "_row");
fileRow.one(".percentdone").set("text", event.percentLoaded + "%");
});
```
<p>When the upload starts, we disable the uploader and the `Upload Files` button until the upload process is complete:</p>
```
uploader.on("uploadstart", function (event) {
uploader.set("enabled", false);
Y.one("#uploadFilesButton").addClass("yui3-button-disabled");
Y.one("#uploadFilesButton").detach("click");
});
```
<p>When each individual file upload completes, we update the table row corresponding with the file with the appropriate
message:</p>
```
uploader.on("uploadcomplete", function (event) {
var fileRow = Y.one("#" + event.file.get("id") + "_row");
fileRow.one(".percentdone").set("text", "Finished!");
});
```
<p>On `totaluploadprogress` events, we report the overall upload progress in the top-right message container. If the
`bytesLoaded` property from the event payload is equal to the `bytesTotal` property, that means that the entire upload
has completed and the selection UI can be reset and re-enabled:</p>
```
uploader.on("totaluploadprogress", function (event) {
Y.one("#overallProgress").setContent("Total uploaded: <strong>" + event.percentLoaded + "%" + "</strong>");
if (event.bytesLoaded == event.bytesTotal) {
uploadDone = true;
uploader.set("enabled", true);
uploader.set("fileList", []);
Y.one("#uploadFilesButton").removeClass("yui3-button-disabled");
Y.one("#uploadFilesButton").on("click", function () {
});
Y.one("#overallProgress").set("text", "Uploads complete!");
}
});
```
<p>Finally, we add the `click` event listener to the "Upload Files" button to start the file upload process:</p>
```
Y.one("#uploadFilesButton").on("click", function () {
});
```
<h2>Full Source Code For this Example</h2>
```
{{>uploader-multiple-source}}
```