FancyUpload - Swiff meets Ajax (v2.0)
Swiff meets Ajax for powerful and elegant uploads.
FancyUpload is a file-input replacement which features an unobtrusive, multiple-file selection
menu and queued upload with an animated progress bar. It is easy to setup, is server independent,
completely styleable via CSS and XHTML and uses MooTools to work in all modern browsers.
Showcase “Queued Photo Uploader (Fixed)”
Showcase with FancyUpload preview version.
The Action Happens Here
What happens?
Check the automated log file after upload. The PHP script does not save the files but logs every request.
Check the Firebug console for event debugging logs. Filesize is limited to 2Mb (client- and serverside).
Do Not:
- … copy this example and ask why it doesn’t upload the files. It only logs the uploaded images!
- … copy this example without changing the XHTML, the CSS or the images!
- … skip all validation on the server and blindly move the files!
Please Do:
- … take this showcase as a code example about processing and validating the uploaded file and create your own server code.
- … adapt the XHTML, the CSS and the images to your needs.
- … edit the provided source to fit your needs and submit patches to the author
JavaScript & MooTools
window.addEvent('load', function() { // For testing, showing the user the current Flash version. document.getElement('h3 + p').appendText(' Detected Flash ' + Browser.Plugins.Flash.version + '!'); var swiffy = new FancyUpload2($('demo-status'), $('demo-list'), { url: $('form-demo').action, fieldName: 'photoupload', path: '../../source-fixed/Swiff.Uploader.swf', limitSize: 2 * 1024 * 1024, // 2Mb onLoad: function() { $('demo-status').removeClass('hide'); $('demo-fallback').destroy(); }, // The changed parts! debug: true, // enable logs, uses console.log target: 'demo-browse' // the element for the overlay (Flash 10 only) }); /** * Various interactions */ $('demo-browse').addEvent('click', function() { /** * Doesn't work anymore with Flash 10: swiffy.browse(); * FancyUpload moves the Flash movie as overlay over the link. * (see opeion "target" above) */ swiffy.browse(); return false; }); /** * The *NEW* way to set the typeFilter, since Flash 10 does not call * swiffy.browse(), we need to change the type manually before the browse-click. */ $('demo-select-images').addEvent('change', function() { var filter = null; if (this.checked) { filter = {'Images (*.jpg, *.jpeg, *.gif, *.png)': '*.jpg; *.jpeg; *.gif; *.png'}; } swiffy.options.typeFilter = filter; }); $('demo-clear').addEvent('click', function() { swiffy.removeFile(); return false; }); $('demo-upload').addEvent('click', function() { swiffy.upload(); return false; }); });
XHTML Markup
<form action="/project/fancyupload/2-0/showcase/photoqueue/script.php" method="post" enctype="multipart/form-data" id="form-demo"> <fieldset id="demo-fallback"> <legend>File Upload</legend> <p> Selected your photo to upload.<br /> <strong>This form is just an example fallback for the unobtrusive behaviour of FancyUpload.</strong> </p> <label for="demo-photoupload"> Upload Photos: <input type="file" name="photoupload" id="demo-photoupload" /> </label> </fieldset> <div id="demo-status" class="hide"> <p> <a href="#" id="demo-browse">Browse Files</a> | <input type="checkbox" id="demo-select-images" /> Images Only | <a href="#" id="demo-clear">Clear List</a> | <a href="#" id="demo-upload">Upload</a> </p> <div> <strong class="overall-title">Overall progress</strong><br /> <img src="../../assets/progress-bar/bar.gif" class="progress overall-progress" /> </div> <div> <strong class="current-title">File Progress</strong><br /> <img src="../../assets/progress-bar/bar.gif" class="progress current-progress" /> </div> <div class="current-text"></div> </div> <ul id="demo-list"></ul> </form>
PHP Script
<?php $result = array(); if (isset($_FILES['photoupload']) ) { $file = $_FILES['photoupload']['tmp_name']; $error = false; $size = false; if (!is_uploaded_file($file) || ($_FILES['photoupload']['size'] > 2 * 1024 * 1024) ) { $error = 'Please upload only files smaller than 2Mb!'; } if (!$error && !($size = @getimagesize($file) ) ) { $error = 'Please upload only images, no other files are supported.'; } if (!$error && !in_array($size[2], array(1, 2, 3, 7, 8) ) ) { $error = 'Please upload only images of type JPEG.'; } if (!$error && ($size[0] < 25) || ($size[1] < 25)) { $error = 'Please upload an image bigger than 25px.'; } $addr = gethostbyaddr($_SERVER['REMOTE_ADDR']); $log = fopen('script.log', 'a'); fputs($log, ($error ? 'FAILED' : 'SUCCESS') . ' - ' . preg_replace('/^[^.]+/', '***', $addr) . ": {$_FILES['photoupload']['name']} - {$_FILES['photoupload']['size']} byte\n" ); fclose($log); if ($error) { $result['result'] = 'failed'; $result['error'] = $error; } else { $result['result'] = 'success'; $result['size'] = "Uploaded an image ({$size['mime']}) with {$size[0]}px/{$size[1]}px."; } } else { $result['result'] = 'error'; $result['error'] = 'Missing file or internal error!'; } if (!headers_sent() ) { header('Content-type: application/json'); } echo json_encode($result); ?>
CSS Stylesheet
#demo-status { background-color: #F9F7ED; padding: 10px 15px; width: 420px; } #demo-status .progress { background: white url(../../assets/progress-bar/progress.gif) no-repeat; background-position: +50% 0; margin-right: 0.5em; } #demo-status .progress-text { font-size: 0.9em; font-weight: bold; } #demo-list { list-style: none; width: 450px; margin: 0; } #demo-list li.file { border-bottom: 1px solid #eee; background: url(../../assets/file.png) no-repeat 4px 4px; } #demo-list li.file.file-uploading { background-image: url(../../assets/uploading.png); background-color: #D9DDE9; } #demo-list li.file.file-success { background-image: url(../../assets/success.png); } #demo-list li.file.file-failed { background-image: url(../../assets/failed.png); } #demo-list li.file .file-name { font-size: 1.2em; margin-left: 44px; display: block; clear: left; line-height: 40px; height: 40px; font-weight: bold; } #demo-list li.file .file-size { font-size: 0.9em; line-height: 18px; float: right; margin-top: 2px; margin-right: 6px; } #demo-list li.file .file-info { display: block; margin-left: 44px; font-size: 0.9em; line-height: 20px; clear } #demo-list li.file .file-remove { clear: right; float: right; line-height: 18px; margin-right: 6px; }
This example and the accompanying sources/assets are © 2008-2009 by Harald Kirschner and available under The MIT License. For debugging and profiling the scripts and their markup download Firefox and use addons like Firebug and Web Developer Toolbar.
1231 Comments
Please use the support forums for discussing the project, asking questions or posting bug-fixes!