The YUI Uploader leverages Flash to provide file upload functionality beyond the native browser-based methods. Specifically, the Uploader allows for:
- Multiple file selection in a single "Open File" dialog.
- File extension filters to facilitate the user's selection.
- Progress tracking for file uploads.
- A range of available file metadata: filename, size, date created, date modified, and author.
- A set of events dispatched on various aspects of the file upload process: file selection, upload progress, upload completion, data return, and upload errors.
- Inclusion of additional data in the file upload POST request.
- Faster file upload on broadband connections (due to the modified SEND buffer size).
Important usage notes:
- Because of security requirements of the Flash Player, the Uploader has to receive a direct user input in order to initiate file browsing.
- Because of limitations of the Flash Player, the Uploader does not transmit session data in the header of the POST requests it sends to the server. In order to transmit the session data, the developer will need to programmatically extract it from the DOM and send as part of the body of the POST request.
- The Uploader SWF should always be served from an HTTP server due to Flash Player's restricted local security model.
- The Uploader SWF should not be placed in a container with
visibility
set tohidden
, ordisplay
set tonone
, whether at initialization of the page, or at any subsequent time. Because of how Flash Player is instantiated, setting these properties to these values will result in the loss of communication between the Flash player and the DOM. If it's necessary to hide the instance of the Uploader on the page, its size should be set to 0x0 - The Uploader requires Flash Player 9.0.45 or higher, with Flash Player 10.1 preferred. The latest version of Flash Player is available at the Adobe Flash Player Download Center.
- Because of a bug in IE6, IE7 and IE8, the Uploader SWF does not function properly when loaded from local cache. For that reason, in IE6, IE7 and IE8, it is best to prevent cache loading of the SWF. See the examples for one possible workaround of this issue.
Getting Started
To include the source files for Uploader (deprecated version) and its dependencies, first load the YUI seed file if you haven't already loaded it.
<script src="http://yui.yahooapis.com/3.8.0/build/yui/yui-min.js"></script>
Next, create a new YUI instance for your application and populate it with the
modules you need by specifying them as arguments to the YUI().use()
method.
YUI will automatically load any dependencies required by the modules you
specify.
<script> // Create a new YUI instance and populate it with the required modules. YUI().use('uploader-deprecated', function (Y) { // Uploader (deprecated version) is available and ready for use. Add implementation // code here. }); </script>
For more information on creating YUI instances and on the
use()
method, see the
documentation for the YUI Global Object.
Using the Uploader
In this section, we'll describe how to use the uploader in detail. First, let's look at the structure of the uploader module under the hood.
Anatomy of the Uploader
Hybrid structure
The Uploader uses the native functionality of the widely adopted Adobe Flash player to provide methods for sending
multiple files to the server and tracking the progress of the uploads. In order to control the Flash player,
the Uploader uses the Flash player's built-in ExternalInterface
class for communicating with JavaScript.
ExternalInterface
allows JavaScript to call exposed methods on an instance of a Flash player, and allows
the instance of the Flash player to call arbitrary global methods in the global JavaScript space.
In order to properly instantiate the Flash player and communicate with it, the Uploader uses YUI SWF utility. The SWF utility
encapsulates the instance of the Flash player and standardizes communication with it (e.g., all Flash player method calls are
wrapped in SWF's callSWF
function; correspondingly, all method calls from the Flash player are exposed as SWF's events.)
Presence in the DOM
Because of security restrictions of the Flash player, browsing for files cannot be initialized via a method call or a simulated
event. Such initialization must come from a hardware device controlled by the user (mouse or keyboard). As a consequence, the instance
of the Flash player tied to a specific instance of the Uploader must be present on the page that uses it and must be clickable. Clicking
this instance of the Flash player always triggers the standard OS "Browse" dialog (unless the Uploader has been specifically disable()
ed.)
The Uploader provides two methods for displaying its instance of the Flash Player: either as a Flash-based "button" with a developer-provided skin Sprite, or as a fully transparent overlay that can be placed above another UI element to mimic native behavior. When the user interacts with the Uploader Flash Player instance, all mouse events are bubbled up to JavaScript and are dispatched by the instance of the Uploader.
Instantiating and Configuring the Uploader
To put the Uploader on the page, simply create a new instance of Y.Uploader
and provide it with the reference to the container in which it should be placed:
YUI({...}).use('uploader',function (Y) { // Default everything var uploader = new Y.Uploader({boundingBox:"#uploaderContainerID"}); // Use a custom button skin: var uploader = new Y.Uploader({ boundingBox:'#uploaderContainerID', buttonSkin : 'assets/buttonSkin.jpg' }); // Use a custom SWF URL: var uploader = new Y.Uploader({ boundingBox:'#uploaderContainerID', swfURL : 'assets/uploader.swf' }); });
The only required configuration attribute for the Uploader is the boundingBox
property, which specifies the container where the Uploader will be rendered. By default, the Uploader is assigned the same dimensions as its container, is transparent, and allows the user to select a single file with any extension. Below are the three other configuration attributes available for Slider:
Property | Description | Default |
---|---|---|
buttonSkin |
Specifies an image Sprite to use as the skin for the Uploader. | N/A |
swfURL |
An alternative path to the Flash SWF file used by the uploader | YUI CDN location |
transparent |
Whether to render the Uploader SWF as transparent or opaque (useful if keyboard access is needed) | true |
Because the Flash player runs in a thread separate from JavaScript, the Uploader methods and properties will not set correctly until the initialization event is fired. Make sure to subscribe to that event and perform subsequent method calls inside its handler:
uploader.on("uploaderReady", setupUploader); var setupUploader = function (event) { // Uploader method calls / property setting here. }
File extension filtering and multiple file selection
While the browse dialog in the Uploader is standard for the user's specific operating system, there are two parameters that you can modify to control the user's experience. The first parameter is fileFilters
, which allows you to specify file extensions that can be selected. The second parameter is a Boolean multiFiles
, which specifies whether the user can select many files, or just one. These parameters are set as follows:
uploader.set("multiFiles", true); var fileFilters = [{description:"Images", extensions:"*.jpg;*.png;*.gif"}, {description:"Videos", extensions:"*.avi;*.mov;*.mpg"}]; newuploader.set("fileFilters", fileFilters);
Note that even though file extensions are filtered, the user can circumvent this filter by entering "*.*" in the text field of the "Browse" dialog. Therefore, it is up to the developer to check that the files that were selected do, in fact, have correct extensions
The upload process
After the user has selected a file (or files) to be uploaded, the selected file list is returned as an array in the fileSelect
event. At that point, you can either have the user initialize the actual upload process, or initialize it automatically, without any additional user action.
Each selected file is uploaded in its own POST request. You can either upload each file individually, and manage the queue using your own code, or use the Uploader's built-in queue management. To upload a single file, the following method call is made:
uploader.upload("file0", "upload.php");
To upload all files using the built-in queue manager, you can call the uploadAll()
method:
uploader.uploadAll("upload.php");
You can also upload a subset of the provided files, using an overloaded call to upload():
uploader.upload(['file0', 'file1'], "upload.php");
To monitor the upload progress, you can subscribe to the uploadprogress
event, which reports the number of bytes uploaded, and the number of total bytes that needs to be uploaded:
uploader.on(uploadprogress, reportProgress); function reportProgress (event) { Y.log("Percent of " + event.id + " uploaded: " + Math.round((100 * event.bytesLoaded / event.bytesTotal)) + "%"); }
Uploader events
Uploader fires the following events during operation:
Event | When | Payload |
---|---|---|
uploaderReady |
Uploader ready to accept method calls | None |
fileselect |
The user has selected some files to upload | { fileList : {fileID: {id:String, name:String, size:Number, date:Number}, ...} } |
uploadstart |
A specific file's upload has started. | {id : String} |
uploadprogress |
TCP socket reports how many bytes of a specific file have been uploaded | {id:String, bytesLoaded:Number, bytesTotal:Number} |
uploadcomplete |
A specific file has been uploaded to the server. | {id:String} |
uploadcompletedata |
The server has returned data in response to the upload POST request. | {id:String, data:String} |
This is not an exhaustive list. See the API docs for a complete listing.