Toolkit:multifile uploads
From Surebert wiki
Contents |
Overview
sb.uploadButton allows the client to select and uploads multiple files using Adobe Flex/Flash.
Requirements
Requires Adobe Flash Player 9+
Advantages
- Client never needs to leave page or fresh as with traditional file upload
- Client can sleect multiple files to upload at once
- The system returns uploads progress so that you can present the end user with that data
- You can send additional data back with the file
- You can validate file size, type before upload to prevent wasted time for files that are too big
- You can limit the number of files uploaded at once
- The button can be styled using simple style properties
- There are many event handlers to deal with the upload
Example
javascript code
var uploader = new sb.uploadButton({ debug : true, maxFiles : 5, maxFileSizeK : 5000000, url : 'http://frameworkdev.sv/uploads/test', data : { friend : 'tim', nano : "Hello there timmy's dog" }, onReturnData : function(file){ sb.objects.alert(file); }, onBeforeBrowse : function(){ this.data.username = $('#username_input').value; return true; }, onSelect : function(filenames){ return true; }, onExceedsMaxFiles : function(){}, onExceedsMaxFileSizeK : function(file){}, onError : function(data){ alert(data.message); }, styles : { backgroundColor : '0x00FF00', backgroundColorRoll : '0xFFFF00', borderColor : '0xFF0000', color : '0xFF0000', cornerRadius : '15', borderThickness : '0', fontSize : 16, width : 62, height : 24, fontSize : 16, font : 'Tahoma', htmlText : 'upload now' } }); uploader.embed('#chicken');
Properties
These properties determine how the upload button works.
method
String - The method to send the data from the buttons .data property. 'post' or 'get'
javascript code
myUploadButton.method = 'post';
debug
Boolean - If it is set to true, then the upload button debugs data to the flash debug log for simple debugging. Using this functionality requires that you have the flash debug player installed. Any flash developer should already ahave this installed. Simly read the log to debug what is going on.
javascript code
myUploadButton.debug = true;
debugLevel
Integer - Can be set to 1 or 2. At level 2 all data is debugged to the debug log including data returned from the server upon upload
javascript code
myUploadButton.debugLevel = 2;
maxFiles
Integer - The maximum number files that the upload button will accept. If exceeded the upload is canceled and the onMaxFiles() handler is fired.
javascript code
myUploadButton.maxFiles = 5;
maxFileSizeK
Integer - The maximum file size in K that the upload button will accept. This is on a per file basis not the total of all uploaded files. If execeed, the upload is canceled and the onExceedsMaxFileSizeK handler is fired.
javascript code
myUploadButton.maxFileSizeK = 1024;
url
String - The url to upload the files to.
javascript code
myUploadButton.url = '/upload/files';
data
Object - Data to send along with the upload. You can set this property in the object argument of the constructor, but you can also alter or add to it in onBeforeBrowse, which is when the user clicks the browse for files button. That way if they have added additional information to a form on the page, etc you can send that data as well.
javascript code
myUploadButton.data = { key : 'value', otherKey : 'otherValue };
acceptedFileTypes
String - The file types to accept for upload, separated by a semicolon
javascript code
//accepts only certain types uploadButton.acceptedFileTypes = '*.gif;*.jpg;*.png;*.pdf;*.zip'; //accepts any file uploadButton.acceptedFileTypes = '*.*'; //accepts any file name data.xls uploadButton.acceptedFileTypes = 'data.xls';
Methods
cancelAll
Cancels all uploads currently in progress
javascript code
myUploadButton.cancelAll();
setStyles(styles)
Sets the button styles base don the flex style properties for the button
javascript code
this.setStyles( backgroundColor : '0x00FF00', backgroundColorRoll : '0xFFFF00', borderColor : '0xFF0000', color : '0xFF0000', cornerRadius : '15', borderThickness : '0', fontSize : 16, width : 62, height : 24, fontSize : 16, font : 'Tahoma' );
embed
javascript code
//embeds the upload button in the node with the id chicken myUploadButton.embed('#chicken');
Event Handlers
The following fire when specific events occcur during upload
onBeforeBrowse()
Fires when the user clicks the upload button before the file browser opens. If it returns false, then the upload is canced. This allows to cancel the file upload based on if other actions have been completed or not. E.g. you want them to fill out a filename box before clicking the upload file button. Here you can check for that value and them alert the message and return false to force them to fill it out before upload.
javascript code
myUploadButton.onBeforeBrowse = function(){ if(someInput.value == ''){ alert('You must fill out some value before clicking upload!'); return false; } };
onCancelBrowse
Fires if the user hits the cancel button in the file browser.
javascript code
myUploadButton.onCancelBrowse = function(){ //cleanup any progress bar you created, etc };
onSelect
Fires after the files are selected.
javascript code
myUploadButton.onSelect = function(){ //do something };
onOpen(file)
Fires after the files are opened for upload. Passes file data about the file to the event handler. passes one object file with properties file.name, file.size, file.sizeK, file.type
javascript code
myUploadButton.onOpen = function(file){ //do something };
onProgress
Fires periodically as a file uploads alerting you of the progress in percent, deosn't seem to fire for really quick uploads on local server, must return something from the serer for this to fire, can be a simple space
Passes one object 'file' with properties e.g. file.name, file.size, file.sizeK, file.type, file.bytesLoaded, file.bytesTotal, file.percent
javascript code
myUploadButton.onOpen = function(file){ //do something };
onAllProgress
Fires each time one more file is uploaded until the que is empty. Passes one argument files with properties files.total, files.remaining
javascript code
myUploadButton.onAllProgress = function(files){ //do something };
onExceedsMaxFiles
Fires when a user selects too many files. Passes one object argument 'file' files.chosen, files.limit, files.message
javascript code
myUploadButton.onExceedsMaxFiles = function(file){ alert(files.chosen); };
onExceedsMaxFileSizeK(file)
Fires when a file exceeds the maximum file size specified and is therefore not uploaded. Passes one object argument 'file' file.name, file.size, file.sizeK, file.exceededBy, file.limit, file.message
javascript code
myUploadButton.onExceedsMaxFileSizeK = function(file){ alert(file.exceededBy); };
onError(data)
Fires if the upload is canceled due to an error e.g. HTTP error, security error. Pass one object argument 'file' file.name, file.size, file.sizeK, file.type, file.error
javascript code
myUploadButton.onError = function(data){ alert(file.exceededBy); };
onReturnData
Fires when the data is returned from the server, , must beturn something from the serer for this to fire, can be a simple space. Pass one object argument 'file' file.name, file.size, file.sizeK, file.type, file.data. File.data is any data returned from the server's upload script. The uplaod script must return something, at least a blank space for this to fire.
javascript code
myUploadButton.onReturnData = function(file){ alert(file.data); };
onComplete
Fires when a file is done uploading, must beturn something from the server for this to fire, can be a simple space. Pass one object argument 'file' file.name, file.size, file.sizeK, file.type. This functionality has generally been replaced by onReturnData()
javascript code
myUploadButton.onComplete = function(file){ alert(file.name+' has been uploaded'); };
onAllComplete
Fires when all uploads for this upload instance are complete. One object argument 'files' files.total
javascript code
myUploadButton.onAllComplete = function(files){ alert(files.total+' files have been uploaded'); };
onCancelFile
Fires when one file in the que is canceled by filename with myUploadButton.cancel(file.name); or once per file when upload.cancel() is fired without a name specified. One object argument 'file' file.name
javascript code
myUploadButton.onCancelFile = function(file){ alert(' upload canceled for '+file.name); };
onCancelAll
Fires once when the upload que is canceled using upload.cancel();
javascript code
myUploadButton.onCancelAll = function(file){ alert('uploads canceled'); };
On The Server Side
The files get passed one at a time to whatever script you have set as url. The files are send as regular form based file uploads would be.
Using plain old PHP
php code
print_r($_FILES['Filedata']);
Using the surebert framework
php code
print_r($this->request->files['Filedata']);
Moving Uploaded Files
In this example we are moving the uploaded file into the public/content directory from which it can be served statically. You would not want to do this with files that should not be publicly available. Instead move them into somewhere in /private where they could be proxyed based on App::$user credentials.
php code
if(isset($this->request->files['Filedata'])){ if(move_uploaded_file($this->request->files['Filedata']['tmp_name'], ROOT.'/public/content/'.$this->request->files['Filedata']['name'])){ echo 'uploaded'; } else { echo 'not uploaded'; } }
File uploads with authenticated sites that use sessions
Unfortunately, on mac, the flash player does not properly pass cookies which can include the session cookie. In order for the session to work, sb.uploadButton passes the SBF_ID as post data back to the script. You can then check for that use it to start your session id. If you are not using the surebert framework you could easily pass the cookies yourself with the uploadButton data by reading document.cookie with javascript.
You would replace /myview/upload with the view you are uploading to
php code
/** * Needed in order to allow sessions to work on flash player for mac */ if( isset(Gateway::$request->post['SBF_ID']) && stristr(Gateway::$agent, 'Adobe Flash Player') && Gateway::$request->path == '/myview/upload' ){ session_id(Gateway::$request->post['SBF_ID']); } session_start();
If using this internally at Roswell with the ticket mirror you will need to also edit your .htaccess file and add an exception to the re-write for that view that accepts the files.
You would replace /myview/upload with the view you are uploading to
text code
RewriteCond %{REQUEST_URI} !gateway.php$
RewriteCond %{REQUEST_URI} !/myview/upload$
RewriteCond %{HTTP_COOKIE} !rticketi
RewriteRule .* http://ntlm-ticket-writer.roswellpark.org?r=%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING} [R=302,L]Debugging with Flash Log
In order to debug interaction with the serverside you will need to install the flash debug player.