485 lines
13 KiB
JavaScript
485 lines
13 KiB
JavaScript
/**
|
|
* The main upload panel, which ties all the functionality together.
|
|
*
|
|
* In the most basic case you need just to set the upload URL:
|
|
*
|
|
* @example
|
|
* var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
|
|
* uploaderOptions: {
|
|
* url: '/api/upload'
|
|
* }
|
|
* });
|
|
*
|
|
* It uses the default ExtJsUploader to perform the actual upload. If you want to use another uploade, for
|
|
* example the FormDataUploader, you can pass the name of the class:
|
|
*
|
|
* @example
|
|
* var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
|
|
* uploader: 'Ext.ux.upload.uploader.FormDataUploader',
|
|
* uploaderOptions: {
|
|
* url: '/api/upload',
|
|
* timeout: 120*1000
|
|
* }
|
|
* });
|
|
*
|
|
* Or event an instance of the uploader:
|
|
*
|
|
* @example
|
|
* var formDataUploader = Ext.create('Ext.ux.upload.uploader.FormDataUploader', {
|
|
* url: '/api/upload'
|
|
* });
|
|
*
|
|
* var uploadPanel = Ext.create('Ext.ux.upload.Panel', {
|
|
* uploader: formDataUploader
|
|
* });
|
|
*
|
|
*/
|
|
Ext.define('Ext.ux.upload.Panel', {
|
|
extend : 'Ext.panel.Panel',
|
|
|
|
requires : [
|
|
'Ext.ux.upload.ItemGridPanel',
|
|
'Ext.ux.upload.Manager',
|
|
'Ext.ux.upload.StatusBar',
|
|
'Ext.ux.upload.BrowseButton',
|
|
'Ext.ux.upload.Queue'
|
|
],
|
|
|
|
config : {
|
|
|
|
/**
|
|
* @cfg {Object/String}
|
|
*
|
|
* The name of the uploader class or the uploader object itself. If not set, the default uploader will
|
|
* be used.
|
|
*/
|
|
uploader : null,
|
|
|
|
/**
|
|
* @cfg {Object}
|
|
*
|
|
* Configuration object for the uploader. Configuration options included in this object override the
|
|
* options 'uploadUrl', 'uploadParams', 'uploadExtraHeaders', 'uploadTimeout'.
|
|
*/
|
|
uploaderOptions : null,
|
|
|
|
/**
|
|
* @cfg {boolean} [synchronous=false]
|
|
*
|
|
* If true, all files are uploaded in a sequence, otherwise files are uploaded simultaneously (asynchronously).
|
|
*/
|
|
synchronous : true,
|
|
|
|
/**
|
|
* @cfg {String} uploadUrl
|
|
*
|
|
* The URL to upload files to. Not required if configured uploader instance is passed to this panel.
|
|
*/
|
|
uploadUrl : '',
|
|
|
|
/**
|
|
* @cfg {Object}
|
|
*
|
|
* Params passed to the uploader object and sent along with the request. It depends on the implementation of the
|
|
* uploader object, for example if the {@link Ext.ux.upload.uploader.ExtJsUploader} is used, the params are sent
|
|
* as GET params.
|
|
*/
|
|
uploadParams : {},
|
|
|
|
/**
|
|
* @cfg {Object}
|
|
*
|
|
* Extra HTTP headers to be added to the HTTP request uploading the file.
|
|
*/
|
|
uploadExtraHeaders : {},
|
|
|
|
/**
|
|
* @cfg {Number} [uploadTimeout=6000]
|
|
*
|
|
* The time after the upload request times out - in miliseconds.
|
|
*/
|
|
uploadTimeout : 60000,
|
|
|
|
/**
|
|
* @cfg {Object/String}
|
|
*
|
|
* Encoder object/class used to encode the filename header. Usually used, when the filename
|
|
* contains non-ASCII characters. If an encoder is used, the server backend has to be
|
|
* modified accordingly to decode the value.
|
|
*/
|
|
filenameEncoder : null,
|
|
|
|
// strings
|
|
textOk : 'OK',
|
|
textUpload : 'Upload',
|
|
textBrowse : 'Browse',
|
|
textAbort : 'Abort',
|
|
textRemoveSelected : 'Remove selected',
|
|
textRemoveAll : 'Remove all',
|
|
|
|
// grid strings
|
|
textFilename : 'Filename',
|
|
textSize : 'Size',
|
|
textType : 'Type',
|
|
textStatus : 'Status',
|
|
textProgress : '%',
|
|
|
|
// status toolbar strings
|
|
selectionMessageText : 'Selected {0} file(s), {1}',
|
|
uploadMessageText : 'Upload progress {0}% ({1} of {2} souborů)',
|
|
|
|
// browse button
|
|
buttonText : 'Browse...'
|
|
},
|
|
|
|
/**
|
|
* @property {Ext.ux.upload.Queue}
|
|
* @private
|
|
*/
|
|
queue : null,
|
|
|
|
/**
|
|
* @property {Ext.ux.upload.ItemGridPanel}
|
|
* @private
|
|
*/
|
|
grid : null,
|
|
|
|
/**
|
|
* @property {Ext.ux.upload.Manager}
|
|
* @private
|
|
*/
|
|
uploadManager : null,
|
|
|
|
/**
|
|
* @property {Ext.ux.upload.StatusBar}
|
|
* @private
|
|
*/
|
|
statusBar : null,
|
|
|
|
/**
|
|
* @property {Ext.ux.upload.BrowseButton}
|
|
* @private
|
|
*/
|
|
browseButton : null,
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
initComponent : function() {
|
|
|
|
this.queue = this.initQueue();
|
|
|
|
this.grid = Ext.create('Ext.ux.upload.ItemGridPanel', {
|
|
queue : this.queue,
|
|
textFilename : this.textFilename,
|
|
textSize : this.textSize,
|
|
textType : this.textType,
|
|
textStatus : this.textStatus,
|
|
textProgress : this.textProgress
|
|
});
|
|
|
|
this.uploadManager = this.createUploadManager();
|
|
|
|
this.uploadManager.on('uploadcomplete', this.onUploadComplete, this);
|
|
this.uploadManager.on('itemuploadsuccess', this.onItemUploadSuccess, this);
|
|
this.uploadManager.on('itemuploadfailure', this.onItemUploadFailure, this);
|
|
|
|
this.statusBar = Ext.create('Ext.ux.upload.StatusBar', {
|
|
dock : 'bottom',
|
|
selectionMessageText : this.selectionMessageText,
|
|
uploadMessageText : this.uploadMessageText
|
|
});
|
|
|
|
Ext.apply(this, {
|
|
title : this.dialogTitle,
|
|
autoScroll : true,
|
|
layout : 'fit',
|
|
uploading : false,
|
|
items : [
|
|
this.grid
|
|
],
|
|
dockedItems : [
|
|
this.getTopToolbarConfig(), this.statusBar
|
|
]
|
|
});
|
|
|
|
this.on('afterrender', function() {
|
|
this.stateInit();
|
|
}, this);
|
|
|
|
this.callParent(arguments);
|
|
},
|
|
|
|
createUploadManager : function() {
|
|
var uploaderOptions = this.getUploaderOptions() || {};
|
|
|
|
Ext.applyIf(uploaderOptions, {
|
|
url : this.uploadUrl,
|
|
params : this.uploadParams,
|
|
extraHeaders : this.uploadExtraHeaders,
|
|
timeout : this.uploadTimeout
|
|
});
|
|
|
|
var uploadManager = Ext.create('Ext.ux.upload.Manager', {
|
|
uploader : this.uploader,
|
|
uploaderOptions : uploaderOptions,
|
|
synchronous : this.getSynchronous(),
|
|
filenameEncoder : this.getFilenameEncoder()
|
|
});
|
|
|
|
return uploadManager;
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*
|
|
* Returns the config object for the top toolbar.
|
|
*
|
|
* @return {Array}
|
|
*/
|
|
getTopToolbarConfig : function() {
|
|
|
|
this.browseButton = Ext.create('Ext.ux.upload.BrowseButton', {
|
|
itemId : 'button_browse',
|
|
buttonText : this.buttonText
|
|
});
|
|
this.browseButton.on('fileselected', this.onFileSelection, this);
|
|
|
|
return {
|
|
xtype : 'toolbar',
|
|
itemId : 'topToolbar',
|
|
dock : 'top',
|
|
items : [
|
|
this.browseButton,
|
|
'-',
|
|
{
|
|
itemId : 'button_upload',
|
|
text : this.textUpload,
|
|
iconCls : 'ux-mu-icon-action-upload',
|
|
scope : this,
|
|
handler : this.onInitUpload
|
|
},
|
|
'-',
|
|
{
|
|
itemId : 'button_abort',
|
|
text : this.textAbort,
|
|
iconCls : 'ux-mu-icon-action-abort',
|
|
scope : this,
|
|
handler : this.onAbortUpload,
|
|
disabled : true
|
|
},
|
|
'->',
|
|
{
|
|
itemId : 'button_remove_selected',
|
|
text : this.textRemoveSelected,
|
|
iconCls : 'ux-mu-icon-action-remove',
|
|
scope : this,
|
|
handler : this.onMultipleRemove
|
|
},
|
|
'-',
|
|
{
|
|
itemId : 'button_remove_all',
|
|
text : this.textRemoveAll,
|
|
iconCls : 'ux-mu-icon-action-remove',
|
|
scope : this,
|
|
handler : this.onRemoveAll
|
|
}
|
|
]
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*
|
|
* Initializes and returns the queue object.
|
|
*
|
|
* @return {Ext.ux.upload.Queue}
|
|
*/
|
|
initQueue : function() {
|
|
var queue = Ext.create('Ext.ux.upload.Queue');
|
|
|
|
queue.on('queuechange', this.onQueueChange, this);
|
|
|
|
return queue;
|
|
},
|
|
|
|
onInitUpload : function() {
|
|
if (!this.queue.getCount()) {
|
|
return;
|
|
}
|
|
|
|
this.stateUpload();
|
|
this.startUpload();
|
|
},
|
|
|
|
onAbortUpload : function() {
|
|
this.uploadManager.abortUpload();
|
|
this.finishUpload();
|
|
this.switchState();
|
|
},
|
|
|
|
onUploadComplete : function(manager, queue, errorCount) {
|
|
this.finishUpload();
|
|
if (errorCount) {
|
|
this.stateQueue();
|
|
} else {
|
|
this.stateInit();
|
|
}
|
|
this.fireEvent('uploadcomplete', this, manager, queue.getUploadedItems(), errorCount);
|
|
manager.resetUpload();
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*
|
|
* Executes after files has been selected for upload through the "Browse" button. Updates the upload queue with the
|
|
* new files.
|
|
*
|
|
* @param {Ext.ux.upload.BrowseButton} input
|
|
* @param {FileList} files
|
|
*/
|
|
onFileSelection : function(input, files) {
|
|
this.queue.clearUploadedItems();
|
|
this.queue.addFiles(files);
|
|
this.browseButton.reset();
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*
|
|
* Executes if there is a change in the queue. Updates the related components (grid, toolbar).
|
|
*
|
|
* @param {Ext.ux.upload.Queue} queue
|
|
*/
|
|
onQueueChange : function(queue) {
|
|
this.updateStatusBar();
|
|
|
|
this.switchState();
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
*
|
|
* Executes upon hitting the "multiple remove" button. Removes all selected items from the queue.
|
|
*/
|
|
onMultipleRemove : function() {
|
|
var records = this.grid.getSelectedRecords();
|
|
if (!records.length) {
|
|
return;
|
|
}
|
|
|
|
var keys = [];
|
|
var i;
|
|
var num = records.length;
|
|
|
|
for (i = 0; i < num; i++) {
|
|
keys.push(records[i].get('filename'));
|
|
}
|
|
|
|
this.queue.removeItemsByKey(keys);
|
|
},
|
|
|
|
onRemoveAll : function() {
|
|
this.queue.clearItems();
|
|
},
|
|
|
|
onItemUploadSuccess : function(manager, item, info) {
|
|
|
|
},
|
|
|
|
onItemUploadFailure : function(manager, item, info) {
|
|
|
|
},
|
|
|
|
startUpload : function() {
|
|
this.uploading = true;
|
|
this.uploadManager.uploadQueue(this.queue);
|
|
},
|
|
|
|
finishUpload : function() {
|
|
this.uploading = false;
|
|
},
|
|
|
|
isUploadActive : function() {
|
|
return this.uploading;
|
|
},
|
|
|
|
updateStatusBar : function() {
|
|
if (!this.statusBar) {
|
|
return;
|
|
}
|
|
|
|
var numFiles = this.queue.getCount();
|
|
|
|
this.statusBar.setSelectionMessage(this.queue.getCount(), this.queue.getTotalBytes());
|
|
},
|
|
|
|
getButton : function(itemId) {
|
|
var topToolbar = this.getDockedComponent('topToolbar');
|
|
if (topToolbar) {
|
|
return topToolbar.getComponent(itemId);
|
|
}
|
|
return null;
|
|
},
|
|
|
|
switchButtons : function(info) {
|
|
var itemId;
|
|
for (itemId in info) {
|
|
this.switchButton(itemId, info[itemId]);
|
|
}
|
|
},
|
|
|
|
switchButton : function(itemId, on) {
|
|
var button = this.getButton(itemId);
|
|
|
|
if (button) {
|
|
if (on) {
|
|
button.enable();
|
|
} else {
|
|
button.disable();
|
|
}
|
|
}
|
|
},
|
|
|
|
switchState : function() {
|
|
if (this.uploading) {
|
|
this.stateUpload();
|
|
} else if (this.queue.getCount()) {
|
|
this.stateQueue();
|
|
} else {
|
|
this.stateInit();
|
|
}
|
|
},
|
|
|
|
stateInit : function() {
|
|
this.switchButtons({
|
|
'button_browse' : 1,
|
|
'button_upload' : 0,
|
|
'button_abort' : 0,
|
|
'button_remove_all' : 1,
|
|
'button_remove_selected' : 1
|
|
});
|
|
},
|
|
|
|
stateQueue : function() {
|
|
this.switchButtons({
|
|
'button_browse' : 1,
|
|
'button_upload' : 1,
|
|
'button_abort' : 0,
|
|
'button_remove_all' : 1,
|
|
'button_remove_selected' : 1
|
|
});
|
|
},
|
|
|
|
stateUpload : function() {
|
|
this.switchButtons({
|
|
'button_browse' : 0,
|
|
'button_upload' : 0,
|
|
'button_abort' : 1,
|
|
'button_remove_all' : 1,
|
|
'button_remove_selected' : 1
|
|
});
|
|
}
|
|
|
|
});
|