Asynchronous File Upload - YUI’s Approach
Filed Under Javascript | 40 Comments
Tags: Ajax, file upload, Javascript, YUI
Download YUI
Test upload example online
Online Example Source
YUI is a truly amazing framework for those who are writing Ajax applications. Its JavaScript widgets allow programmer to create richly interactive UI components with ease. However, these UI widgets are not very useful unless the end result of the interaction can be saved to the server side. Hence YUI has added Ajax support to most of its widgets. While many people are familiar with YUI Connection Manager's Ajax capability, only a few know that Connection Manager can be used to simulate Ajax-like file upload.
The theory that makes asynchronous file upload work is not complicate, but the code for it to work can be a little bit lengthy if it was developed from the scratch. Since there no reason to reinvent the wheel and YUI's Connection Manager can take care of most of the dirty jobs for us, in this article, I'll show you how to use it to do a simple asynchronous file upload. Because XMLHttpRequest object does not support file upload, the Connection Manager uses inline frame approach. Basically what the Connection Manager does is it creates an invisible IFRAME for file upload and parses the server response once the upload is completed. In the end, what you get is an illusion of Ajax-like file upload interaction. However, since this is an IFRAME, some Ajax events such as success or failure are not available in IFRAME method as they are available in regular Ajax request in YUI.
Preparation
This script uses YUI's Connection Manager, you can either download it to your hard drive or you can include it directly from YUI online repository.
Include the following JavaScript file to your HTML page:
<script type="text/javascript" src="[PATH_TO_YUI]/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="[PATH_TO_YUI]/connection/connection-min.js"></script>
or from YUI repository:
<script type="text/javascript" src="http://yui.yahooapis.com/2.3.0/build/utilities/utilities.js"></script>
HTML Upload Form
Create an upload form as usual and assign the form field an id:
<form action="upload.php" enctype="multipart/form-data" method="post" id="testForm"> <input type="file" name="testFile"/> <input type="button" id="uploadButton" value="Upload"/> </form>
In above case, we've assigned the id testForm to our form.
Coding JavaScript
First, we need to create a event handler to handle the click event of the upload button:
Upload Button Handler:
var onUploadButtonClick = function(e){
//this method is called when upload button is clicked
};
YAHOO.util.Event.on('uploadButton', 'click', onUploadButtonClick);
Call setForm method:
As soon as the user clicks on the upload button, we use Connection Manager to do the actual upload. In order to do so, we must let YUI know which form we are dealing with: we first call setForm method of the Connection Manager, supply the form ID we assigned earlier and set the second argument of the setForm to true to indicate that this is a file upload request.
YAHOO.util.Connect.setForm('testForm', true);
Establish an Asynchronous Request:
Now, we are ready to upload files. Invoke asyncRequest method of the Connection Manager and specify request method as 'POST', the URL where files upload to, and the upload handler. The upload handler is an JavaScript associative array, in which the array key specifies type of event to handle and the array value is a callback function with signature function(response){}.
Since this is a file upload request, we need to handle the upload event. Here's how: in the upload handler, create a key-value pair with "upload" as key and a callback function as value. The callback function will be invoked when the server response is returned. For more information about upload handler, please see Callback Object and File Upload
The argument of the callback function, in this case response, contains information of server response. You can access text contents returned from the server after a file upload request by response.responseText or response.responseXML if the content type is XML. For more information, please visit Connection Manager Upload Case.
var uploadHandler = {
//handle upload case. This function will be invoked after file upload is finished.
upload: function(response) {
alert(response.responseText);
}
};
YAHOO.util.Connect.asyncRequest('POST', 'upload.php', uploadHandler);
Writing Server-Side Code
Your can write your server-side code in any programming language. For demonstration purpose, we will use PHP to handle file upload request. Since this is not an PHP file upload tutorial, I wrote an one line code snip that shows information of an uploaded file. You can use this information to confirm that whether a file has been successfully uploaded or not:
print_r($_FILES);
If everything has gone well and you have this line alert( response.responseText ); in your upload handler (a handler is just a JavaScript function), you should see a message box similar to the one shown below, which indicates the file has been successfully uploaded:
Putting Everything Together
<html>
<head>
<title>YUI File UploadS</title>
<script type="text/javascript" src="[PATH_TO_YUI]/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="[PATH_TO_YUI]/connection/connection-min.js"></script>
<script type="text/javascript">
function init(){
var onUploadButtonClick = function(e){
//the second argument of setForm is crucial,
//which tells Connection Manager this is a file upload form
YAHOO.util.Connect.setForm('testForm', true);
var uploadHandler = {
upload: function(o) {
alert(o.responseText);
}
};
YAHOO.util.Connect.asyncRequest('POST', 'upload.php', uploadHandler);
};
YAHOO.util.Event.on('uploadButton', 'click', onUploadButtonClick);
}
YAHOO.util.Event.on(window, 'load', init);
</script>
</head>
<body>
<form action="upload.php" enctype="multipart/form-data" method="post" id="testForm">
<input type="file" name="testFile"/>
<input type="button" id="uploadButton" value="Upload"/>
</form>
</body>
</html>
Related Reading
Links
- Serving YUI Files from Yahoo! Servers
- Download YUI
- Test upload example online
- PHP File Upload Manual
More interesting posts ...
Leave a Comment
If you would like to make a comment, please fill out the form below.
If you want to post source code, please wrap it with <pre> and </pre>



can you show upload.php source?
What about Form Validation?
To egor:
As stated in the article, upload.php consists only one line of code, which prints out human-readable text of PHP special variable $_FILES array:
< ?php
print_r($_FILES);
?>
You can use this information to verify whether a file is uploaded or not:
Array ( [file] => Array ( [name] => [type] => [tmp_name] => [error] => 4 [size] => 0 ) )Above is a PHP response of
print_r($_FILES);without uploading a file. As you can see,nameandtmp_nameis empty in this case.You can retrieve the content of this response from your JavaScript code by using
response.responseTextin your upload handler.Cheer!
To Rob:
I didn't quite get it what you mean. Can you be more specific?
Do you think there would be an easy way to be ablt to Select Multiple files and then upload them?
on Validation:
If file has not been selected show an error
if file is a certain format: EG jpg,gif etc.
If other form fields are not enetered.
Most upload form will have a title description etc
Doing it like this for years from now, long before the phrase "AJAX" popped up ;) with a little difference:
Im using a JS callback from the Iframe, which i consider a bit more elegant than the $_FILES thingie..
imagine PHP behind the iframe prints out a little , calling back to a function in the original page, giving some status information via parameter (upload status, actual file name after invalid characters stripped out, ... whatever comes to your mind)
i meant "print out a little [EVIL BRACKET]script[/EVIL BRACKET] ;)
It works fine...exactly what I wanted..! Thanks a lot...
If you find nothing is happening when you use he sample code, it may be because the sample at the end of this article assumes you have downloaded the YUI code and amended the path accordingly. If you want to use the YUI server version just change this:
to
Comment above stripped out the code, but I'm sure you can work out the change!
To Rob:
I really don't think you can select multiple files for upload merely from HTML. However, you can create multiple upload filed, i.e.,
<input type="file" name="testFile"/>and upload them in one IFRAME request.Actually I have validated those on the server side. You can test my online upload example, it displays an alert box if no file has been uploaded or the format is not allowed.
exactly what I wanted... thanks a lot...
it will be perfect if there's a process bar...
can you show online demo source
Here's the code for upload in PHP. I removed session management code since it's irrelevant and it reveals too much server detail:
http://thecodecentral.com/wp-content/uploads/2007/09/upload.zip
More about php file upload: http://us3.php.net/features.file-upload
Encoding Json in PHP: http://thecodecentral.com/2007/09/13/easy-json-encodingdecoding-in-php
thanks :)
awesome...
thanks for the tutorial, i will try it..
Hi there... excellent feature! Just wondering if there's an .asp version of upload.php.
Thanks in advance
Decbrad
Sorry I don't have one for asp, but if you already know how to handle file upload in asp, then you are set.
Just handle the upload request like any ordinary file upload request, and output some server responses to indicate the status of the upload, e.g., "upload success" or "file size is too large." The format can be text, HTML, XML or JSON. You have complete control on how to encode the server response.
You can intercept the server response in your upload handler by this line
response.responseText. It's then up to you what to do with this response.I want to show at the same page the list with links to files which i upload. How i can do that?
1) Save those links to an array so you can iterate through them.
2) Create a DIV tag somewhere in the page.
Assuming that you give this DIV an ID called "linkContainer", in your upload handler, you can write something like this:
var con = document.getElementById("linkContainer"); for(var i in links){ var aTag = document.createElement("a"); aTag.href = links[i].href; aTag.appendChild(document.createTextNode(link[i].text); con.appendChild(aTag); con.appendChild(document.createTextNode("br"); }Added:
Similar code is usde in online demonstration, you can take a look that as well.
I dont understand.... :/
Is it possible to do this kind of async upload, without the browser showing its reload progress bar - it would be more pretty:)
Thanks for this. I used it to upload an image and then display the image in the same window. On IE it works fine. On Safari the back button becomes active as if the page had refreshed. If the back button is clicked the image is permanently lost. Is this related to the iframe? Any idea how this can be fixed? Thanks again...
I understand how you are catching files which are too large on the server side, but i don't want to waste bandwidth.. is there a good way to filter them from the client side using YUI?
\@Jav: I don't think so. This is an regular file upload that occurs behind an invisible IFRAME, so the browser will behave just like any other file upload.
\@mfogg: Sorry I can't help you with this one since I don't have a Mac with me.
\@david: JavaScript doesn't have the ability to access file system (excluding "ActiveX's FileSystemObject"http://www.codeproject.com/useritems/AJAXUpload.asp, but it is not cross-browser compatible), so you run out of luck. Not sure which server technology you are using, but if you can get the upload progress bar working for your technology, I believe you can terminate the upload inside of
updateProgress()function or whatever it called (it is the code segment that periodically sends upload progress back to the client).Another solution that I recently discovered is that through Flash, more information.
we want to see upload.php
oops i didn't know that question was already answered
Showing the content of listImages.php and image.php would also be helpful. plz
Why not just zip-up the contents of your online demonstration code and package it as a deliverable for all those curious folk (of which i am one), i too would like to see the contents of listImages.php and image.php
Good call, here's the zip file:
http://thecodecentral.com/wp-content/uploads/2008/01/asyncupload.zip
Just what I need. Thanks a lot :)
Kudos Cuong, really good code.
please kindly show the code in reset.php:P
@dave:
I believe I posted that 2 posts above your post. :||
How do upload a doc file on server and then again open in it RTE?
ex Suppose user from RTE user wants to upload a doc file on server then after processing this file from server again it should display in RTE.
Then he can able to save it on his hard drive.
@dinesh
First of all, what is RTE? I suppose it stands for Rich Text Editor. In spite of what kind of text editor you use, the procedure for asynchronous upload remains the same.
Basically, on client-side, you need a file upload form that let the user to upload the doc file, and use YUI to do background uploading. In your upload handler, you need to listen to upload event, this is where you display processed result returned from the server.
var uploadHandler = { //handle upload case. This function will be invoked after file upload is finished. upload: function(response) { //content of the doc file shall be response.responseText //use JavaScript to inject it into RTE } };On server-side, you need a write a script to handle uploading of the doc file, and you can do whatever server-side processing to the doc file in this script. After the file upload is completed, you need to output the content of this doc file in the format of your choice, which can be JSON, XML, HTML, so that the upload handler on the client-side can consume it.
If you have doubt, take a look the source of online demonstration:
http://thecodecentral.com/wp-content/uploads/2008/01/asyncupload.zip
Hey, It simply didn't work for me!
[...] Asynchronous File Upload - YUI [...]
very nice, if i get it to work i will use it in my next project
;-) www.spooXe.com
[...] Asynchronous File Upload - YUI’s Approach : Code Central (tags: AJAX YUI fileupload) [...]
[...] Asynchronous File Upload / YUI [...]