Yahoo! Developer Network Home - Help

YDN Site Search

# YUI Library Examples: Uploader Control (experimental): Advanced Uploader Example

# Uploader Control (experimental): Advanced Uploader Example

In this example, we will pair the YUI Uploader Control with the DataTable Control to give the user visual feedback on the progress of their file upload. When the user selects multiple files for upload, a DataTable will be populated with the list of files and their sizes. When the user starts the upload process, they'll see progress bars next to each of the files as they upload.

Note: The YUI Uploader Control requires Flash Player 9.0.45 or higher. The latest version of Flash Player is available at the Adobe Flash Player Download Center.

Note: The YUI Uploader Control requires the uploader.swf Flash file that is distributed as part of the YUI package, in the uploader/assets folder. Copy the uploader.swf to your server and set the YAHOO.Uploader.SWFURL variable to its full path.

Note: This example requires a backend component to receive uploaded files. Download the source for this example below to use on your own server.

Download example source.

When you have the example running on your own server, it should look like the screenshot below:

## Using Uploader with the DataTable Control to Handle Multi-file Uploads with Progress Feedback

Just as we did in the Simple Example, we start with including all the necessary files. We will need the base YUI files, as well as files specific to the Logger, Uploader, and DataTable.

<html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Uploader With DataTable Example</title> <!-- Required YUI files --> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.1/build/fonts/fonts-min.css" /> <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.5.1/build/datatable/assets/skins/sam/datatable.css" /> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/element/element-beta.js"></script> <!-- Required JSON files --> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/json/json-beta.js"></script> <!-- Required Datasource and Datatable files --> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/datasource/datasource-beta.js"></script> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/datatable/datatable-beta.js"></script> <!-- Main Uploader script --> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/uploader/uploader-experimental.js"></script> <!-- Logger CSS and JS --> <link type="text/css" rel="stylesheet" href="http://yui.yahooapis.com/2.5.1/build/logger/assets/skins/sam/logger.css"> <script type="text/javascript" src="http://yui.yahooapis.com/2.5.1/build/logger/logger-min.js"></script> </head> <body class="yui-skin-sam">

Next, just as we did in the Simple Example, we add a container `div` where the Uploader Control will be placed. If you don't want it to be visible, feel free to set the size of the container element to `height:0; width:0` (with `overflow:hidden`). We also add the "Browse" and "Upload" buttons:

<h1>Uploader With DataTable Example</h1> <div id="toBeReplaced" style="width:400px;height:210px"> Unable to load Flash content. You can download the latest version of Flash Player from the <a href="http://www.adobe.com/go/getflashplayer">Adobe Flash Player Download Center</a>. </div> <input id="browseBtn" name="browse" value="Browse for Images" onclick="browse()" type="button" /> <input id="uploadBtn" name="upload" value="Upload Selected" onclick="upload()" type="button" />

We also need to put in one additional placeholder `div` into which we'll render the DataTable:

<div id="single" style="margin-top:2em;"></div>

Next, we initialize the Logger and the Uploader, and place them on the page. We'll also initialize an `uploadCounter` that we will use to upload the files one at a time, a `fileIdHash` to keep the record between rows of the DataTable and the file ids, and a `dataArr` where we'll hold the necessary file information (we'll also use it to instantiate the DataTable).

this.myLogReader = new YAHOO.widget.LogReader(); YAHOO.widget.Uploader.SWFURL = "http://yui.yahooapis.com/2.5.1/build/uploader/assets/uploader.swf"; var uploader = new YAHOO.widget.Uploader( "toBeReplaced" ); uploader.addListener('fileSelect',onFileSelect); uploader.addListener('uploadComplete',onUploadComplete); uploader.addListener('uploadProgress',onUploadProgress); uploader.addListener('uploadStart',onUploadStart); var uploadCounter = 0; var fileIdHash; var dataArr;

In the `browse()` function, we clear the file list, and call the `uploader.browse` function, passing `true` as the first argument (which means the user will be able to select multiple files by holding the Shift button). We also pass the file extension filter array, allowing for three types of image files:

function browse() { uploader.clearFileList(); uploader.browse(true, [{description:"Images", extensions:"*.jpg;*.png;*.gif"}]); }

Once we have received the list of files from the `onFileSelect` function (defined below), we will call the `createDataTable` function that will populate our variables, create a new DataSource based on the file list, and create the DataTable to display it:

function createDataTable(entries) { rowCounter = 0; fileIdHash = []; dataArr = []; for(var i in entries) { var entry = entries[i]; dataObj = {}; for (var j in entry) { dataObj[j] = entry[j]; } dataArr.push(dataObj); fileIdHash[dataObj["id"]] = rowCounter; rowCounter++; } this.allData = {data: dataArr}; var myColumnDefs = [ {key:"name", label: "File Name", sortable:true}, {key:"size", label: "Size", sortable:true}, {key:"progress", label: "Upload progress", sortable:false} ]; this.myDataSource = new YAHOO.util.DataSource(this.allData); this.myDataSource.dataType = YAHOO.util.DataSource.TYPE_JSARRAY; this.myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON; this.myDataSource.responseSchema = { resultsList: ["data"], fields: ["id","name","created","modified","type", "size", "progress"] }; this.singleSelectDataTable = new YAHOO.widget.DataTable("single", myColumnDefs, this.myDataSource, { caption:"Files To Upload", selectionMode:"single" }); }

In the `upload` function, we initiate the upload of the file that's indicated by the `uploadCounter`. The `uploadCounter` is incremented every time a preceding upload is complete (see `onUploadComplete` below):

function upload() { YAHOO.log(dataArr); var idToUpload = dataArr[uploadCounter]["id"]; uploader.upload(idToUpload, 'YOUR UPLOAD URL HERE'); document.getElementById('uploadBtn').disabled = true; }

When we receive the `uploadProgress` event, we need to update the corresponding row of the DataTable. We use a simple HTML horizontal rule as a progress bar and update its width based on the progress of the upload:

function onUploadProgress(event) { rowNum = fileIdHash[event["id"]]; prog = Math.round(100*(event["bytesLoaded"]/event["bytesTotal"])); progbar = "<hr style=\"color: #f00; background-color: #f00; text-align:left; margin: 0 auto 0 0; height: 5px; width: " + prog + "px\"/>"; singleSelectDataTable.updateRow(rowNum, {name: dataArr[rowNum]["name"], size: dataArr[rowNum]["size"], progress: progbar}); }

When files are selected, we call `createDataTable` (described above):

function onFileSelect(event) { fileList = event.fileList; YAHOO.log(event); createDataTable(fileList); }

After the start of each file upload, it may be awhile before the first `uploadProgress` event comes in. Thus, we want the user know that the upload has started. On the `uploadStart` event, we update the respective row of the DataTable to reflect that the upload is in progress:

function onUploadStart(event) { YAHOO.log(event); rowNum = fileIdHash[event["id"]]; singleSelectDataTable.updateRow(rowNum, {name: dataArr[rowNum]["name"], size: dataArr[rowNum]["size"], progress: "Starting..."}); }

Finally, when the upload is complete, we either initiate the next upload, or, if the `uploadCounter` has equalized with the number of files, we send an appropriate message to the Logger and halt:

function onUploadComplete(event) { YAHOO.log(event); rowNum = fileIdHash[event["id"]]; progbar = "<hr style=\"color: #f00; background-color: #f00; text-align:left; margin: 0 auto 0 0; height: 5px; width: 100px\"/>"; singleSelectDataTable.updateRow(rowNum, {name: dataArr[rowNum]["name"], size: dataArr[rowNum]["size"], progress: progbar}); if (uploadCounter < dataArr.length - 1) { uploadCounter++; upload(); } else { YAHOO.log("All files uploaded!"); } }

### Uploader Control (experimental) Examples:

- Simple Uploader Example
- Advanced Uploader Example

### More Uploader Control (experimental) Resources:

- User's Guide (external)
- API Documentation
- Cheat Sheet PDF (external)

Copyright © 2008 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings