PDA

View Full Version : swfupload extjs api



dfdsfd
12 Apr 2008, 11:59 PM
Hi,
Maybe this can save time for anybody planning to use swfupload with extjs.
This code require more tests, I only use it with firefox 2.0 on macox 10.5 and windows vista with last flash version.
No example, no demo...

d2


Ext.ns('Ext.ux');

/**
* Ext.ux.FileUpload
*
* Simple rewrite of swfupload api for easier
* integration on ext advanced upload components
*
* ExtJS : 2.0.2
* Swfupload : 2.1.0
*
* @author OXYS.net
* @version 0.0.1
* @extends Ext.util.Observable
*/

Ext.ux.FileUploadFile = Ext.extend(Ext.util.Observable, {

id: '',
name: '',
size: '',
type: '',
start: null,
end: null,
creationDate: '',
modificationDate: '',
remainingTime: null,
bytesComplete: 0,
status: '',
queueError:null,
uploadError:null,
fileUploadInstance: null,
params:{},

constructor: function(fileData, params, fileUploadInstance) {
this.id = fileData.id;
this.name = fileData.name;
this.type = fileData.type;
this.size = fileData.size;
this.bytesComplete = 0;
this.creationDate = fileData.creationdate;
this.modificationDate = fileData.modificationdate;
this.status = Ext.ux.FileUpload.FILE_STATUS.QUEUED;

for (param in params) {
fileUploadInstance.addFileParam(this.id, param, params[param]);
}

this.fileUploadInstance = fileUploadInstance;

this.addEvents(
'uploadprogress',
'uploaderror',
'uploadsuccess',
'uploadcomplete'
);
},

fileQueueError: function(errorCode, message){
this.status = Ext.ux.FileUpload.FILE_STATUS.ERROR;
this.queueError = errorCode;
},
uploadStart: function(){
this.start = new Date();
},
uploadProgress: function(bytesComplete, bytesTotal){
this.status = Ext.ux.FileUpload.FILE_STATUS.IN_PROGRESS;
this.bytesComplete = bytesComplete;
this.fireEvent("uploadprogress", this);
},
uploadSuccess: function(serverData){
this.status = Ext.ux.FileUpload.COMPLETE;
},
uploadError: function(serverData, errorCode, message){
this.status = Ext.ux.FileUpload.FILE_STATUS.ERROR;
this.uploadError = errorCode;
},
uploadComplete: function(){
this.end = new Date();
},


progress: function() {
if(this.size == 0 ) return 0;
return (this.bytesComplete/this.size);
},

startUpload: function(){
this.fileUploadInstance.startUpload(this.id);
},

cancelUpload: function(){
this.status = Ext.ux.FileUpload.FILE_STATUS.CANCELLED;
this.fileUploadInstance.cancelUpload(this.id);
},

});

/**
* Ext.ux.FileUpload
*
* ExtJS : 2.0.2
* Swfupload : 2.1.0
*
* @author OXYS.net
* @version 0.0.1
* @extends Ext.Component
*/

Ext.ux.FileUpload = Ext.extend(Ext.Component, {

/**
* @cfg Upload file after select without calling method startUpload manualy
*/
autoUpload: true
/**
* @cfg
*/
,uploadUrl: ''
/**
* @cfg
*/
,filePostName: 'Filedata'
/**
* @cfg
*/
,postParams: {}
/**
* @cfg
*/
,useQueryString: false
/**
* @cfg
*/
,fileTypes: '*.*'
/**
* @cfg
*/
,fileTypesDescription: 'All Files'
/**
* @cfg Default zero means "unlimited"
*/
,fileSizeLimit: 0
/**
* @cfg
*/
,fileUploadLimit: 0
/**
* @cfg
*/
,fileQueueLimit: 0
/**
* @cfg
*/
,flashUrl: 'libs/js/swfupload/Flash9/swfupload_f9.swf'
/**
* @cfg
*/
,flashColor: '#FFFFFF'
/**
* @cfg {boolean}
*/
,debugEnabled:false
/**
* @cfg
*/
,customSettings: {}

/**
* private
*/
,initComponent:function() {

this.addEvents(
/**
* @event initialize
* Fires when the file upload component is fully initialized (including the flash)
* @param {Ext.ux.FileUpload} this
*/
'initialize',
/**
* @event beforefiledialogshow
* Fires before the file dialog is displayed
* @param {Ext.ux.FileUpload} this
*/
'beforefiledialogshow',
/**
* @event filequeued
* @param {Ext.ux.FileUpload, file} this
*/
'filequeued',
/**
* @event filequeueerror
* @param {Ext.ux.FileUpload, file, Ext.ux.FileUpload.QUEUE_ERROR, message} this
*/
'filequeueerror',
/**
* @event afterdialogcomplete
* @param {Ext.ux.FileUpload, numFilesSelected, numFilesQueued} this
*/
'afterfiledialogcompleted',
/**
* @event uploadstart
* @param {Ext.ux.FileUpload, file} this
*/
'uploadstart',
/**
* @event uploadprogress
* @param {Ext.ux.FileUpload, file, bytesComplete, bytesTotal} this
*/
'uploadprogress',
/**
* @event uploaderror
* @param {Ext.ux.FileUpload, file, errorCode, message} this
*/
'uploaderror',
/**
* @event uploadsuccess
* @param {Ext.ux.FileUpload, file, serverData} this
*/
'uploadsuccess',
/**
* @event uploadcompleted
* @param {Ext.ux.FileUpload, file} this
*/
'uploadcompleted'


);
this.eventQueue = [];
this.files = [];
this.fileParams = {};
this.movieName = "SWFUpload_" + Ext.ux.FileUpload.movieCount++;
Ext.ux.FileUpload.instances[this.movieName] = this;
var s = document.createElement("div");
Ext.DomHelper.applyStyles(s, {width: '1px',height : '1px'});
s.innerHTML=this.getFlashHTML();
document.body.appendChild(s);
this.el = document.getElementById(this.movieName);
}

/**
* private
* getStats gets the file statistics object. It looks like this (where n is a number):
*/
,getStats : function () {
return this.callFlash("GetStats");
}

/**
* private
* setStats changes the SWFUpload statistics. You shouldn't need to
* change the statistics but you can. Changing the statistics does not
* affect SWFUpload accept for the successful_uploads count which is used
* by the upload_limit setting to determine how many files the user may upload.
*/
,setStats : function (statsObject) {
this.callFlash("SetStats", statsObject);
}

/**
* private
* setCredentials that will be used to authenticate to the uploadUrl.
* Note: This feature does not work. It has been added in anticipation of
* the Flex 3 SDK which has not been released yet.
*/
,setCredentials : function (name, password) {
this.callFlash("SetCrednetials", name, password);
}

/**
* private
* getFile retrieves a File object by ID or Index. If the file is
* not found then 'null' is returned.
*/
,getFileObject : function (file) {
for(i=0;i<this.files.length;i++) {
if(this.files[i].id == file.id) {
return this.files[i];
}
}
return null;
}

/**
* private
* addFileParam sets a name/value pair that will be posted with the
* file specified by the Files ID. If the name already exists then the
* exiting value will be overwritten.
*/
,addFileParam : function (fileId, name, value) {
return this.callFlash("AddFileParam", fileId, name, value);
}

/**
* private
* removeFileParam removes a previously set (by addFileParam) name/value
* pair from the specified file.
*/
,removeFileParam : function (fileId, name) {
this.callFlash("RemoveFileParam", fileId, name);
}

/**
* private
* setUploadUrl changes the uploadUrl setting.
*/
,setUploadURL : function (url) {
this.uploadUrl = url.toString();
this.callFlash("SetUploadURL", url);
}

/**
* private
* setPostParams changes the postParams setting
*/
,setPostParams : function (paramsObject) {
this.postParams = paramsObject;
this.callFlash("SetPostParams", paramsObject);
}

/**
* private
* setFileTypes changes the fileTypes setting and the fileTypesDescription setting
*/
,setFileTypes : function (types, description) {
this.fileTypes = types;
this.fileTypesDescription = description;
this.callFlash("SetFileTypes", types, description);
}

/**
* private
* setFileSizeLimit changes the fileSizeLimit setting
*/
,setFileSizeLimit : function (fileSizeLimit) {
this.fileSizeLimit = fileSizeLimit;
this.callFlash("SetFileSizeLimit", fileSizeLimit);
}

/**
* private
* setFileUploadLimit changes the fileUploadLimit setting
*/
,setFileUploadLimit : function (fileUploadLimit) {
this.fileUploadLimit = fileUploadLimit;
this.callFlash("SetFileUploadLimit", fileUploadLimit);
}

/**
* private
* setFileQueueLimit changes the fileQueueLimit setting
*/
,setFileQueueLimit : function (fileQueueLimit) {
this.fileQueueLimit = fileQueueLimit;
this.callFlash("SetFileQueueLimit", fileQueueLimit);
}

/**
* private
* setFilePostName changes the filePostName setting
*/
,setFilePostName : function (filePostName) {
this.filePostName = filePostName;
this.callFlash("SetFilePostName", filePostName);
}

/**
* private
* setUseQueryString changes the useQueryString setting
*/
,setUseQueryString : function (useQueryString) {
this.useQueryString = useQueryString;
this.callFlash("SetUseQueryString", useQueryString);
}

/**
* private
* setDebugEnabled changes the debugEnabled setting
*/
,setDebugEnabled : function (debugEnabled) {
this.debugEnabled = debugEnabled;
this.callFlash("SetDebugEnabled", debugEnabled);
}

,flashReady: function () {
// Check that the movie element is loaded correctly with its ExternalInterface methods defined
if (typeof(this.el.StartUpload) !== "function") {
throw "ExternalInterface methods failed to initialize.";
}
this.fireEvent("initialize", this);
}

,fileDialogStart: function () {
this.fireEvent("beforefiledialogshow", this);
}

,fileQueued: function (fileFlash) {
file = new Ext.ux.FileUploadFile(fileFlash, this.fileParams, this);
this.files.push(file);
this.fireEvent("filequeued", this, file);
}

,fileQueueError: function (fileFlash, errorCode, message) {
file = new Ext.ux.FileUploadFile(fileFlash, this.fileParams, this);
this.files.push(file);
file.fileQueueError(errorCode, message);
this.fireEvent("filequeueerror", this, file, errorCode, message);
}

,fileDialogComplete: function(numFilesSelected, numFilesQueued) {
if (this.autoUpload == true) {
this.startUpload();
}
this.fireEvent("afterfiledialogcompleted", this, numFilesSelected, numFilesQueued);
}

,uploadStart: function (fileFlash) {
file = this.getFileObject(fileFlash);
file.uploadStart();
this.fireEvent("uploadstart", this, file);
this.returnUploadStart(fileFlash);
}

,uploadProgress: function (fileFlash, bytesComplete, bytesTotal) {
file = this.getFileObject(fileFlash);
file.uploadProgress(bytesComplete, bytesTotal);
this.fireEvent("uploadprogress", this, file, bytesComplete, bytesTotal);
}

,uploadError: function (fileFlash, errorCode, message) {
file = this.getFileObject(fileFlash);
file.uploadError(errorCode, message);
this.fireEvent("uploaderror", this, file, errorCode, message);
}

,uploadSuccess: function (fileFlash, serverData) {
file = this.getFileObject(fileFlash);
file.uploadSuccess(serverData);
this.fireEvent("uploadsuccess", this, file, serverData);
}

,uploadComplete: function (fileFlash) {
file = this.getFileObject(fileFlash);
file.uploadComplete();
if (this.autoUpload == true) {
this.startUpload();
}
this.fireEvent("uploadcompleted", this, file);
}

,returnUploadStart: function (fileFlash) {
file = this.getFileObject(fileFlash);
this.callFlash("ReturnUploadStart", true);
}

,debug: function (message) {
//console.debug(message);
}

/**
* private
* callFlash handles function calls made to the Flash element.:
*/
,callFlash: function () {
functionName = arguments[0];
if (typeof(this.el[functionName]) === "function") {
if (arguments.length === 1) {
return this.el[functionName]();
} else if (arguments.length === 2) {
return this.el[functionName](arguments[1]);
} else if (arguments.length === 3) {
return this.el[functionName](arguments[1], arguments[2]);
} else if (arguments.length === 4) {
return this.el[functionName](arguments[1], arguments[2], arguments[3]);
} else {
throw "Too many arguments";
}
} else {
throw "Invalid function name";
}
}

/**
* private
* selectFile causes a File Selection Dialog window to appear. This
* dialog only allows 1 file to be selected.
*/
,selectFile: function (fileParams) {
this.fileParams = fileParams;
this.callFlash("SelectFile");
}

/**
* private
* selectFiles causes a File Selection Dialog window to appear/ This
* dialog allows the user to select any number of files
* Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
* If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around
* for this bug.
*/
,selectFiles: function (fileParams) {
this.fileParams = fileParams;
this.callFlash("SelectFiles");
}

/**
* private
* startUpload starts uploading the first file in the queue unless
* the optional parameter 'fileId' specifies the ID
*/
,startUpload: function (fileId) {
// NOTE: Testing this without using a setTimeout. Since StartUpload was reworked to use ReturnUploadStart
// it might not be necessary anymore
this.callFlash("StartUpload", fileId);
}

/**
* private
* cancelUpload cancels any queued file. The fileId parameter
* Cancels a the file upload. You must specify a file_id
* must be specified.
*/
,cancelUpload: function (fileId) {
this.callFlash("CancelUpload", fileId);
}

/**
* private
* stopUpload stops the current upload and requeues the file at the beginning of the queue.
* If nothing is currently uploading then nothing happens.
*/
,stopUpload: function () {
this.callFlash("StopUpload");
}


/**
* private
* getFlashHTML generates the object tag needed to embed the flash in to the document
*/
,getFlashHTML: function () {
// Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.flashUrl, '" width="1" height="1" style="-moz-user-focus: ignore;">',
'<param name="movie" value="', this.flashUrl, '" />',
'<param name="bgcolor" value="', this.flashColor, '" />',
'<param name="quality" value="high" />',
'<param name="menu" value="false" />',
'<param name="allowScriptAccess" value="always" />',
'<param name="flashvars" value="' + this.getFlashVars() + '" />',
'</object>'].join("");
}

/**
* private
* getFlashVars builds the parameter string that will be passed
* to flash in the flashvars param.
*/
,getFlashVars: function () {
// Build a string from the post param object
var paramString = this.buildParamString();

// Build the parameter string
return ["movieName=", encodeURIComponent(this.movieName),
"&amp;uploadURL=", encodeURIComponent(this.uploadUrl),
"&amp;useQueryString=", encodeURIComponent(this.useQueryString),
"&amp;params=", encodeURIComponent(paramString),
"&amp;filePostName=", encodeURIComponent(this.filePostName),
"&amp;fileTypes=", encodeURIComponent(this.fileTypes),
"&amp;fileTypesDescription=", encodeURIComponent(this.fileTypesDescription),
"&amp;fileSizeLimit=", encodeURIComponent(this.fileSizeLimit),
"&amp;fileUploadLimit=", encodeURIComponent(this.fileUploadLimit),
"&amp;fileQueueLimit=", encodeURIComponent(this.fileQueueLimit),
"&amp;debugEnabled=", encodeURIComponent(this.debugEnabled)].join("");
}

/**
* private
* buildParamString takes the name/value pairs in the post_params setting object
* and joins them up in to a string formatted "name=value&amp;name=value"
*/
,buildParamString: function () {
var postParams = this.postParams;
var paramStringPairs = [];

if (typeof(postParams) === "object") {
for (var name in postParams) {
if (postParams.hasOwnProperty(name)) {
paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
}
}
}

return paramStringPairs.join("&amp;");
}
});
SWFUpload = Ext.ux.FileUpload;

Ext.ux.FileUpload.instances = []
Ext.ux.FileUpload.movieCount = 0;

Ext.ux.FileUpload.QUEUE_ERROR = {
QUEUE_LIMIT_EXCEEDED : -100,
FILE_EXCEEDS_SIZE_LIMIT : -110,
ZERO_BYTE_FILE : -120,
INVALID_FILETYPE : -130
};
Ext.ux.FileUpload.UPLOAD_ERROR = {
HTTP_ERROR : -200,
MISSING_UPLOAD_URL : -210,
IO_ERROR : -220,
SECURITY_ERROR : -230,
UPLOAD_LIMIT_EXCEEDED : -240,
UPLOAD_FAILED : -250,
SPECIFIED_FILE_ID_NOT_FOUND : -260,
FILE_VALIDATION_FAILED : -270,
FILE_CANCELLED : -280,
UPLOAD_STOPPED : -290
};
Ext.ux.FileUpload.FILE_STATUS = {
QUEUED : -1,
IN_PROGRESS : -2,
ERROR : -3,
COMPLETE : -4,
CANCELLED : -5
};

dot99
13 Apr 2008, 11:46 PM
Please, give an example.

Bruno.SantAnna
15 Apr 2008, 9:56 AM
var swfu = new Ext.ux.FileUpload({
uploadUrl: '/common/filemanagerUpload.action',
flashUrl: '/common/scripts/swfupload/swfupload_f9.swf',
fileSizeLimit: 10485760,
fileUploadLimit: 100,
postParams: {
uID: uID
}
});


later I tried
swfu.selectFiles();

firebug shows a null pointer exception (see attachment);


same behavior in windows / linux
same behavior in ie / firefox.


As our buddy said in the previous post... an usage example should be very welcome...

by the way.. your class is very clear.. congratulations

dfdsfd
19 Apr 2008, 11:15 PM
Could you try this ?

http://public.david.pau.oxys.net/swfuploadapi/demo.html

KarlOKeeffe
15 Oct 2008, 6:09 AM
Great component, an excellently commented and organised.

I think I've found a couple of bugs with the Ext.ux.FileUploadFile uploadError function.

1. It expects a serverData parameter, but this is never passed. And thus it mixes up the errorCode and message parameters

2. The function overwrites itself with the errorCode. This causes problems if you stop and then restart a download. The uploadError function will never be called a second time.

Here is my fix. Lines 75 to 80:



uploadError: function(errorCode, message){
console.log(arguments);
this.status = Ext.ux.FileUpload.FILE_STATUS.ERROR;
this.uploadErrorCode = errorCode;
this.fireEvent("uploaderror", this);
},

galdaka
15 Oct 2008, 7:09 AM
Could you try this ?

http://public.david.pau.oxys.net/swfuploadapi/demo.html


Not work in IE.

Thanks in advance,