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.