SWFUpload jQuery Plugin
When I first stumbled across SWFUpload about two years ago I was impressed by how easy it was to implement. However, their example code has always bugged me as being rather crap, having to assign a separate global event handler for each event, and the lack of multiple handlers for a single event.
Using jQuery (the solution to all things painful), I've written a plugin to create a real event dispatcher for SWFUpload without modifying the SWFUpload core!
The SWFUpload jQuery Plugin
This plugin makes working with SWFUpload easier!
Get straight to the source code at my SWFUpload jQuery Plugin repository on GitHub.
And the benefits are...
- Native jQuery event handling using .bind()
- Ability to assign multiple callbacks per event
- Makes multiple SWFUpload instances on a single page easier to manage
- Ability to completely separate SWFUpload object from UI code (callbacks)
- Assign event handlers before SWFUpload instance is even created!
- No global functions or variables needed!
- A nice, chainable solution!
Live Examples
Here are some live examples you can pull apart. Although the UI is not pretty, it demonstrates how you listen to events, and from there you can create whatever UI you want.
Although these examples upload to a PHP script on my server, the uploaded files are not saved.
How do I use it?
If you know how to use SWFUpload already, the following should be fairly easy to consume.
$(function(){
$('.swfupload-control').swfupload({
// Backend Settings
upload_url: "../upload.php", // Relative to the SWF file (or you can use absolute paths)
// File Upload Settings
file_size_limit : "102400", // 100MB
file_types : "*.*",
file_types_description : "All Files",
file_upload_limit : "10",
file_queue_limit : "0",
// Button Settings
button_image_url : "../multiinstancedemo/XPButtonUploadText_61x22.png", // Relative to the SWF file
button_placeholder_id : "spanButtonPlaceholder",
button_width: 61,
button_height: 22,
// Flash Settings
flash_url : "../swfupload/swfupload.swf"
});
// assign our event handlers
$('.swfupload-control')
.bind('fileQueued', function(event, file){
// start the upload once a file is queued
$(this).swfupload('startUpload');
})
.bind('uploadComplete', function(event, file){
alert('Upload completed - '+file.name+'!');
// start the upload (if more queued) once an upload is complete
$(this).swfupload('startUpload');
});
});
<div class="swfupload-control">
<span id="spanButtonPlaceholder"></span>
</div>
How does it work?
Rather than creating a SWFUpload instance and assigning handlers directly, it associates the SWFUpload instance with an element in the DOM, and all events handlers are bound to that DOM element.
Calling methods on the SWFUpload instance
The following code will execute the startUpload method on all SWFUpload instances that exist within the selector .your-swfupload-control.
$('.your-swfupload-control').swfupload('startUpload');
Getting properties on the SWFUpload instance
Sometimes you just need to get at the SWFUpload instance... easy!
var swfu = $.swfupload.getInstance('.some-selector-for-your-control');
alert(swfu.settings.custom_settings.your_custom_setting);
Additional event handlers
Due to the way SWFUpload works, all event names must be defined before the SWFUpload instance is created. This means if you are using any plugins that define additional events, you'll need to add them to the handler list before the SWFUpload instance is created.
$.swfupload.additionalHandlers('some_plugin_handler');
The source code
If you missed it the first time, you can download all the source code including all support files and example files from my SWFUpload jQuery Plugin repository on GitHub.
Enjoy!
Comments
66 Responses to “SWFUpload jQuery Plugin”
Leave a Reply
General Statement
When implementing SWFUpload or other flash-enabled upload widgets, please provide graceful degradation for linux users:
http://bugs.adobe.com/jira/browse/FP-377
nice script
@Mike: I like the Workaround adobe suggests.
"Workaround (if any): Use Mac OS or Windows OS to perform uploads, where the exact same SWF works fine."
@opus131: in that quote, Adobe shows its incompetency.
@opus131: I propose a better workaround:
"Workaround (if any): stop using Flash in your site. Use W3C standard and open technologies instead."
@Andy: I probably should have added tags.
sarcams tags, that is....
lets get back to the subject -
nice script Adam, thanks very much for sharing.
Thanks for script, why not correctly work in IE6?
@Gibi: The plugin works fine in IE6 - however you must have flash player 9 or higher installed. By default SWFUpload doesn't do flash version detection. There is a plugin to allow this (http://code.google.com/p/swfupload/source/browse/swfupload/trunk/core/plugins/swfupload.swfobject.js) although you'll need to add the additional event handlers to listen to the new events defined in that script.
Thank you, this is great. I hope the dude at SWFUpload will consider adding this to his examples in the future.
Does this work with jQuery 1.2.6? I can't upgrade to the latest 1.3.
I keep getting a type mismatch error on line 29 and I was wondering if it was because of jQuery v1.2.6.
@John: I didn't realise it when I wrote it, but it uses the new jQuery.Event object for triggering custom events and returning values back to SWFUpload. Unfortunately I don't have time at the moment to see if I can make it compatible with 1.2.6, but if you (or someone else) manage to get it working then I am happy to integrate your changes into the source.
I'm confused why is this useful? Is it to change the style of the upload button? You could do that with CSS if you knew what you were doing. I've done upload buttons that are images. It'd be pretty easy to set them as rollovers using sprites, and using Ajax with the right server code, you could do upload monitoring with a progress bar too without Flash. Hence my confusion with using Flash.
If you wanted to do something interesting see if you can download someone's Windows Registry by just having them visit the site. You can't do that with CSS/Ajax.
@SeanBlader: Your questions are really targeted towards SWFUpload itself, rather than my jquery plugin. However, a few reasons people might use flash to upload...
- select and upload multiple files in a queue, selecting what filetypes to be displayed in the file dialog, and having access to file names and sizes *before* uploading
- display a progress bar independent of server-side code (PHP does not give upload status on file uploads)
- "ajax" does not support file uploads
Customising the look of the upload button is supplementary to the above features.
Hi!
I'm trying to use your plugin with swfobject swfupload plugin.
$.swfupload.additionalHandlers('swfupload_loaded_handler');
$('#swfupload-control').swfupload({
upload_url: "/gallery/upload.html",
file_size_limit : "10240",
file_types : "*.*",
file_types_description : "All Files",
file_upload_limit : "0",
flash_url : "/js/swfupload/swfupload.swf",
button_image_url : '/js/swfupload/swfbuttin.png',
button_width : 61,
button_height : 22,
button_placeholder_id : 'test'
})
.bind('swfupload_loaded_handler', function(event){
alert('WTF>!');
});
It just doesn't fire plugin event. I have latest SWFUpload
Hi, just found this plug in. Seems almost exactly like what I was looking for. I have a pretty big form built. In the middle of it there is an option to upload a file.
The way I'd like it to work, is when the file is sent to the server, I want the server to rename it as the DatabaseID.extension and save it in the proper place. Then to return the URL back to the client. So that the User can click the link to see the file. Can that be done? Is there some sort of call back function that can display an error or if successful then somehow replace the text field with the link?
var stats = $('#swfupload-control').swfupload('getStats');
alert(stats.successful_uploads);
alert box undefined
plz...
@micle: Because the swfupload method is chainable, the commands sent as the first parameter don't return a single result. You can however do it like this:
var stats = $.swfupload.getInstance('#swfupload-control').getStats();
alert(stats.successful_uploads);
@Roman: Yes, certainly it can be done... as for how you actually do that on the server, that is up to you. In my php upload script I return an xml string of the uploaded file data, which is returned as the third param in the uploadSuccess event. I then parse that XML, and grab the details and insert what I need into the form. Good luck!
Hi Adam,
Thanks for the response. I was able to get this to work very well for a form with two separate file fields. I was able to even automatically delete an existing file if a new one was uploaded.
But, now I need to do this in a different form that should allow uploading and multiple files at the same time for one field. Not quite sure how to approach that.
If you need to add some other parameters to be posted to the upload.php add something similar to the fileQueued event.
.bind('fileQueued', function(event, file){
// start the upload once a file is queued
var param = {'product' : $("#product").val()};
$(this).swfupload('setPostParams', param);
$(this).swfupload('startUpload');
})
Has anyone gotten this to work with SwfUpload in transparent window mode?
(BTW, great plugin!)
Im trying to get this to grab a variable from the URL. I.E.: http://www.webby.com?id=78234
How do I set it up to grab that id? The way I have it set up so far is that when it uploads, it sends some data to a database, but I don't know how to grab the id from the URL, and use $_GET in the php file. it doesn't work..... Do I have to use the example posted above for adding extra parameters? if so, how? I'm new to Javascript..... sorry guys.
@lemps hero - saved me about 20 minutes of googling
Anyone else seeing Firebug catch errors with the SWFUpload.prototype.cleanUp on page load?
Every load i see a movieElement is undefined, from the comments in the source its supposed to be a IE only function so using the support feature ( JQuery 1.3.x ) i simply just checked if something that returns false across IE 6-8 is true than return ...
// only returns false in IE 6-8 as far as i can see
if ($.support.leadingWhitespace == true) { return; }
but this is a temporary fix, for if i find a better way of am doing something wrong in the first place will change later
I'm a bit confused here. I'm not new at coding but new at Flash and how to refer to it. I'm working in ASP, if it could helps.
The script works well but when i try to save it in a fast way i think i could improve it but i don't have the right idea, i fear.
I changed this line:
upload_url: "upload.asp",
In the file upload.asp there's this piece of code to retrieve the content:
RecByte = Request.TotalBytes
if RecByte > 0 then
Data = Request.BinaryRead(RecByte)
but working with binary data in ASP is best done with ADODB.Stream so, in conclusion, i removed the COM i used to upload files to use another object to save it to the disk.
Is there something am i missing? Does SWFUpload is capable to save directly to the disk?
Thanks Adam,
This is fantastic! I re-wrote the SWFUPload application demo to use your plugin and it work's great. (Although I personally use Java Servlets rather than PHP!).
Below is a link to a re-written "index.php" for the application demo that I produced for anyone who might find this useful (includes a jQuery re-working of the FileProgress Object).
http://docs.google.com/Doc?docid=0AT35gd52_6HRZGhodGJiNDJfNWN4ZzRkNmNr&hl=en
Thanks again,
Mark
would it be possible to redirect to another page when there are no more downloads? I have been googling and looking through the code and using firebug, but so far no luck
Sorry let me rephrase. When the image uploads complete (no more queued images), I want to redirect to another page.
@jason: Yes, just listen to the uploadComplete event like this...
$('.magicUpload-control').bind('uploadComplete', function(event, file){
var stats = $.swfupload.getInstance(this).getStats();
console.debug(stats);
if (stats.files_queued == 0) {
window.location = 'otherpage.htm';
}
});
@Adam: Thanks for your quick response. I actually came up with this a few minutes after posting:
.bind('uploadComplete', function(event, file){
// upload has completed, try the next one in the queue
$(this).swfupload('startUpload');
var swfu = $.swfupload.getInstance('#swfupload-control');
if(swfu.getStats().files_queued == 0){
window.location.href = 'otherpage.htm';
}
})
The upload complete handler was already there, but Is there a reason to use your method rather than mine? Thanks
Is there a way to pass the files to some otherpage.php file that can save them client side? If I'm not mistaken, the files are uploaded to the server's temp folder.
Sorry for bumping, I meant server side :)
@confused uploader: in the example above
upload_url: "../upload.php", // Relative to the SWF file (or you can use absolute paths)
it calls the upload.php via ajax which moves the file from the temp folder to a folder you specify and then delete the tmp file.
@jason: Have you tried it?
doesn't work because the key 'file' in $_FILES does not exist. Can you provide some code that works, please?
Sorry, my code dissapeared from the post. It was:
move_uploaded_file($_FILES['file']['tmp_name'],'upload/' . $_FILES['file']['name']);
echo 'Stored in: ' . 'upload/' . $_FILES['file']['name'];
Try adding this to the settings under $('.swfupload-control').swfupload({
file_post_name: 'file',
Nice plugin thnx!
Is there a way to add something to the upload.php file to create thumbnails? I've tried many different ways of doing this, but nothing works.
@David: Yes, there are ways to do this, however that is out of scope for this tutorial.
SWFUpload has an example as part of their "Application Demo"- http://demo.swfupload.org/v220/index.htm
where can i file my uploaded files. plz help
where can i find my uploaded files. plz help
I'd like to put this into a jQuery modal dialog. Is this possible?
TIA
Nevermind, I had an error in my code. The modal dialog works fine. Now I have another question... how can I change the upload url on the fly?
Hi Adam,
wonderful plugin! :-) I have one question: How do I destroy a swfupload instance on upload complete? I've tried $.swfupload.getInstance('.swfupload-control').destroy(); Doesn't work. :-(
Can you help me?
Greets
@Matt: It should work fine. Here is some example code I've ripped from a project (I was using multiple swfupload instances). Which is almost the same as what you've got.
$('.swfupload-control').each(function(){
var swfu = $.swfupload.getInstance(this);
swfu.destroy();
});
@Ken: I don't think you can change the upload URL on the fly. You would have to destroy and re-create the swfupload instance.
Hi, I can't make your plugin work with the last version of SWFUpload (v2.2.0).
Has anyone else tried to solve the issue?
Regards
Alberto
@Alberto: The plugin should work fine with 2.2.0, you can see in the github repository that is the version I am using for my examples.