Upload progressbars are pretty common on the web these days, they add a touch of feedback to the long and mysterious process of uploading a file to a website. Unfortunately, the most common methods for doing so involve flash or baring that PHP addons that require a recompiling.
In this post I’m going to talk about creating an upload progress bar without the need for a clunky flash object. I’m going to do it with PHP, jQueryUI and a gracefully-degrading framework-independent library.
AJAX Upload
I stumbled across the aptly named AJAX Upload code library (developed by Andrew Valums) at work the other day.
The feature list is quite impressive:
- multiple file select, progress-bar in FF, Chrome, Safari
- drag-and-drop file select in FF, Chrome
- uploads are cancellable
- no external dependencies
- doesn’t use Flash
- fully working with https
- keyboard support in FF, Chrome, Safari
- tested in IE7,8; Firefox 3,3.6,4; Safari4,5; Chrome; Opera10.60;
The package includes a javascript library to handle DOM creation and magical ajax-ey transactions, as well as server-side code written in PHP, CGI, Java and Cold Fusion. The server-side code is required to manage the file upload, where some other solutions use APC or PECL’s uploadprogress, Andrews code makes clever use of PHP streams to track the upload progress.
Relevant snippet from php.php:
function save($path) { $input = fopen("php://input", "r"); $temp = tmpfile(); $realSize = stream_copy_to_stream($input, $temp); fclose($input); if ($realSize != $this->getSize()){ return false; } $target = fopen($path, "w"); fseek($temp, 0, SEEK_SET); stream_copy_to_stream($temp, $target); fclose($target); return true; }
Why didn’t I think of that?!
The Javascript & HTML
Here’s an example of a really basic uploader utilizing jQueryUI’s progressbar.
<!DOCTYPE html> <html> <head> <title>AJAX Upload Test</title> <link rel="stylesheet" href="/path/to/js/uploader/fileuploader.css" type="text/css" > <link rel="stylesheet" href="/path/to/js/css/blitzer/jquery-ui-1.8.13.custom.css" type="text/css" media="screen" title="no title" charset="utf-8"> <script src="/path/to/js/jquery-1.6.1.min.js"></script> <script src="/path/to/js/jquery-ui-1.8.13.custom.min.js"></script> <script src="/path/to/js/jquery.altAlert.js"></script> <script src="/path/to/js/uploader/fileuploader.js"></script> </head> <body> <div id="progressbar"></div> <a href="javascript:void(0)" id="uplbtn">Upload A File!</a> <div id="file-uploader"> <noscript> <p>Please enable JavaScript to use file uploader.</p> <!-- or put a simple form for upload here --> </noscript> </div> <script> $(function() { // Initialize the jQueryUI Progressbar $( "#progressbar" ).progressbar({ value: 0 }); // Initialize the uploader uploader = new qq.FileUploaderBasic({ debug: true, element: document.getElementById('file-uploader'), button: $('#uplbtn')[0], action: '/js/uploader/uploader.php', multiple: false, // Update the progress bar onProgress: function(id, fileName, loaded, total){ var percentLoaded = (loaded / total) * 100; $( "#progressbar" ).progressbar({ value: percentLoaded }); }, // display a fancy message onComplete: function () { alert('Tada!'); } }); }); </script> </body> </html>
The real key here is updating the progressbar value in the uploader’s onChange event.
So there you have it!
Leave a Reply
Only people in my network can comment.