Subversion Repositories eFlore/Applications.cel

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
27 jpm 1
/**
2
 * Makes a Panel to provide the ability to upload multiple files using the SwfUpload flash script.
3
 *
4
 * @author Michael Giddens
5
 * @website http://www.silverbiology.com
6
 * @created 2008-03-06
7
 * @version 0.4
8
 *
9
 * @known_issues
10
 *		- Progress bar used hardcoded width. Not sure how to make 100% in bbar
11
 *		- Panel requires width / height to be set.  Not sure why it will not fit
12
 *		- when panel is nested sometimes the column model is not always shown to fit until a file is added. Render order issue.
13
*/
14
 
15
// Create user extension namespace
16
Ext.namespace('Ext.ux');
17
 
18
Ext.ux.SwfUploadPanel = function(config){
19
 
20
	// Default Params for SwfUploader
21
//	if (!config.title) config.title = 'File Upload';
22
	if (!config.single_select) config.single_select = false;
23
	if (!config.file_types) config.file_types = "*.*";
24
	if (!config.file_types_description) config.file_types_description = "All Files";
25
	if (!config.file_size_limit) config.file_size_limit = "102400"; //100MB
26
	if (!config.file_upload_limit) config.file_upload_limit = "0";
27
	if (!config.file_post_name) config.file_post_name = "Filedata"; // This is the "name" of the file item that the server-side script will receive. Setting this doesn't work in the Linux Flash Player
28
	if (!config.flash_url) config.flash_url = "swfupload_f9.swf"; // Relative to this file
29
	if (!config.debug) config.debug = false;
30
 
31
	this.rec = Ext.data.Record.create([
32
				 {name: 'name'},
33
				 {name: 'size'},
34
				 {name: 'id'},
35
				 {name: 'type'},
36
				 {name: 'creationdate', type: 'date', dateFormat: 'm/d/Y'},
37
				 {name: 'status'},
38
				 {name: 'note'}
39
			]);
40
 
41
	var store = new Ext.data.Store({
42
			reader: new Ext.data.JsonReader({
43
					  id: 'id'
44
				 }, this.rec)
45
	});
46
 
47
	this.suo = new SWFUpload({
48
		upload_url: config.upload_url,
49
		post_params: config.post_params,
50
		file_post_name: config.file_post_name,
51
		file_size_limit : config.file_size_limit,
52
		file_types : config.file_types,
53
		file_types_description : config.file_types_description,
54
		file_upload_limit : config.file_upload_limit,
55
		flash_url : config.flash_url,
56
 
57
		// Event Handler Settings
58
		file_queued_handler : this.fileQueue.createDelegate(this),
59
		file_queue_error_handler : this.fileQueueError.createDelegate(this),
60
		file_dialog_complete_handler : this.fileDialogComplete.createDelegate(this),
61
 
62
		upload_error_handler : this.uploadError.createDelegate(this),
63
		upload_progress_handler : this.uploadProgress.createDelegate(this),
64
		upload_complete_handler : this.uploadComplete.createDelegate(this),
65
 
66
		upload_success_handler : this.fileComplete.createDelegate(this),
67
		upload_error_handler : this.fileCancelled.createDelegate(this),
68
 
69
		swfupload_loaded_handler : this.swfUploadLoaded.createDelegate(this),
70
 
71
		debug: config.debug
72
 
73
	});
74
 
75
	this.progress_bar = new Ext.ProgressBar({
76
			text:'Progress Bar'
77
//			, width: config.width - 7
78
  });
79
 
80
	var cm = new Ext.grid.ColumnModel([{id:'name', header: "Filename", width: 150, dataIndex: 'name'}
81
				,	{id:'size', header: "Size", width: 80, dataIndex: 'size', renderer: this.formatBytes }
82
				,	{id:'status', header: "Status", width: 80, dataIndex: 'status', renderer: this.formatStatus }
83
				,   {id:'note', header: "Note", dataIndex: 'note'}
84
			]);
85
 
86
	config = config || {};
87
	config = Ext.apply(config || {}, {
88
 
89
			store: store
90
		,	cm: cm
91
		, autoExpandColumn: 'note'
92
		, enableColumnResize: true
93
		, enableColumnMove: false
94
 
95
		,	sm: new Ext.grid.RowSelectionModel({singleSelect: config.single_select})
96
		,	tbar: [{	text:'Add File(s)'
97
							, iconCls: 'SwfUploadPanel_iconAdd'
98
							, scope: this
99
							, handler: function() {
100
										if (config.single_file_select)
101
											this.suo.selectFile();
102
										else
103
											this.suo.selectFiles();
104
								}
105
						}, '->', {
106
								text: 'Cancel Upload'
107
							, id: 'cancel'
108
							, iconCls: 'SwfUploadPanel_iconCancel'
109
							, handler: this.stopUpload.createDelegate(this)
110
							, hidden: true
111
						}, {
112
								text: 'Upload File(s)'
113
							, iconCls: 'SwfUploadPanel_iconUpload'
114
							, handler: this.uploadFiles.createDelegate(this)
115
							, hidden: true
116
						}
117
			]
118
 
119
		, bbar: [ this.progress_bar ]
120
 
121
		, listeners: {
122
 
123
							'keydown': function(e) {
124
								// Delete Row
125
								function removeRows(grid) {
126
									var selRecords = grid.getSelections();
127
									for (var i=0; i < selRecords.length; i++) {
128
										if (selRecords[i].data.status != 1) {
129
											grid.suo.cancelUpload(selRecords[i].id);
130
											grid.store.remove(selRecords[i]);
131
										}
132
									}
133
 
134
									if (grid.suo.getStats().files_queued == 0) {
135
										grid.getTopToolbar().items.get(3).setVisible(false);
136
									}
137
 
138
								}
139
 
140
								if (config.confirm_delete) {
141
									if(e.getKey() == e.DELETE) {
142
										Ext.MessageBox.confirm('Remove File','Are you sure you wish to remove this file from queue?', function(e) {
143
											if (e == 'yes') {
144
												removeRows(this);
145
											}
146
										});
147
									}
148
								} else {
149
								    if(e.getKey() == e.DELETE) {
150
										removeRows(this);
151
									}
152
								}
153
							}
154
 
155
							// Prevent the default right click to show up in the grid.
156
						, 'contextmenu': function(e) {
157
								e.stopEvent();
158
							}
159
			}
160
 
161
  });
162
 
163
	cm.defaultSortable = false;
164
 
165
	Ext.ux.SwfUploadPanel.superclass.constructor.apply(this, arguments);
166
 
167
	try {
168
			this.progress_bar.setWidth(this.bbar.getWidth() - 5);
169
			Ext.fly(this.progress_bar.el.dom.firstChild.firstChild).applyStyles("height: 16px");
170
	}	catch (ex1) {
171
	}
172
 
173
	this.on('resize', function() {
174
		this.progress_bar.setWidth(this.bbar.getWidth() - 5);
175
		Ext.fly(this.progress_bar.el.dom.firstChild.firstChild).applyStyles("height: 16px");
176
	});
177
 
178
};
179
 
180
Ext.extend(Ext.ux.SwfUploadPanel, Ext.grid.GridPanel, {
181
 
182
	/**
183
	 * Formats file status
184
	 * @param {Integer} status
185
	 * @return {String}
186
	 */
187
	formatStatus: function(status) {
188
		switch(status) {
189
			case 0: return("Ready");
190
			case 1: return("Uploading...");
191
			case 2: return("Completed");
192
			case 3: return("Error");
193
			case 4: return("Cancelled");
194
		}
195
	}
196
 
197
	/**
198
	 * Formats raw bytes into kB/mB/GB/TB
199
	 * @param {Integer} bytes
200
	 * @return {String}
201
	 */
202
	,	formatBytes: function(bytes) {
203
			if(isNaN(bytes)) {	return (''); }
204
 
205
			var unit, val;
206
 
207
			if(bytes < 999)	{
208
				unit = 'B';
209
				val = (!bytes && this.progressRequestCount >= 1) ? '~' : bytes;
210
			}	else if(bytes < 999999)	{
211
				unit = 'kB';
212
				val = Math.round(bytes/1000);
213
			}	else if(bytes < 999999999)	{
214
				unit = 'MB';
215
				val = Math.round(bytes/100000) / 10;
216
			}	else if(bytes < 999999999999)	{
217
				unit = 'GB';
218
				val = Math.round(bytes/100000000) / 10;
219
			}	else	{
220
				unit = 'TB';
221
				val = Math.round(bytes/100000000000) / 10;
222
			}
223
 
224
			return (val + ' ' + unit);
225
		}
226
 
227
	/**
228
	 * Show notice when error occurs
229
	 * @param {Object, Integer, Integer}
230
	 * @return {}
231
	 */
232
	, uploadError: function(file, error, code) {
233
			switch (error) {
234
				case -200: 	Ext.MessageBox.alert('Error','File not found 404.');
235
										break;
236
				case -230: 	Ext.MessageBox.alert('Error','Security Error. Not allowed to post to different url.');
237
										break;
238
			}
239
		}
240
 
241
 
242
	/**
243
	 * Add file to store / grid
244
	 * @param {file}
245
	 * @return {}
246
	 */
247
	, fileQueue: function(file) {
248
			file.status = 0;
249
			r = new this.rec(file);
250
			r.id = file.id;
251
			this.store.add(r);
252
			this.fireEvent('fileQueued', this, file);
253
		}
254
 
255
	/**
256
	 * Error when file queue error occurs
257
	 */
258
	, fileQueueError: function(a, code, queue_remaining) {
259
			switch (code) {
260
				case -100: 	Ext.MessageBox.alert('Error','The selected files you wish to add exceedes the remaining allowed files in the queue. There are ' + queue_remaining + ' remaining slots.');
261
										break;
262
			}
263
		}
264
 
265
	, fileComplete: function(file, result) {
266
 
267
			var o = Ext.decode(result);
268
			this.fireEvent('fileUploadComplete', this, file, o);
269
 
270
			if ('success' in o && o.success) {
271
			  this.store.getById(file.id).set('status', 2);
272
			  this.store.getById(file.id).set('note', o.message || o.error);
273
			  this.store.getById(file.id).commit();
274
		    }
275
		    else {
276
			  this.store.getById(file.id).set('status', 3);
277
			  this.store.getById(file.id).set('note', o.message || o.error);
278
			  this.store.getById(file.id).commit();
279
		    }
280
 
281
			if (this.suo.getStats().files_queued > 0) {
282
				this.uploadFiles();
283
			} else {
284
				this.getTopToolbar().items.get(2).setVisible(false);
285
				this.getTopToolbar().items.get(3).setVisible(false);
286
 
287
				this.fireEvent('queueUploadComplete', this);
288
 
289
			}
290
 
291
		}
292
 
293
	, fileDialogComplete: function(file_count) {
294
			if (file_count > 0)
295
				this.getTopToolbar().items.get(3).setVisible(true);
296
		}
297
 
298
	, uploadProgress: function(file, current_size, total_size) {
299
			this.store.getById(file.id).set('status', 1);
300
			this.store.getById(file.id).commit();
301
			this.progress_bar.updateProgress(current_size/total_size, 'Uploading file: ' + file.name + ' (' + this.formatBytes(current_size) + ' of ' + this.formatBytes(total_size) + ')');
302
		}
303
 
304
	, uploadComplete: function(file, result) {
305
 
306
			if (this.cancelled) {
307
				this.cancelled = false;
308
			} else {
309
				//var o = Ext.decode(result);
310
 
311
				//this.store.getById(file.id).set('status', 2);
312
				//this.store.getById(file.id).commit();
313
				this.progress_bar.reset();
314
				this.progress_bar.updateText('Progress Bar');
315
 
316
				if (this.remove_completed) {
317
					this.store.remove(this.store.getById(file.id));
318
				}
319
 
320
				//this.fireEvent('fileUploadComplete', this, file, o);
321
			}
322
		}
323
 
324
	, uploadFiles: function() {
325
			this.getTopToolbar().items.get(2).setVisible(true);
326
			this.suo.startUpload();
327
		}
328
 
329
	, addPostParam: function( name, value ) {
330
			this.suo.settings.post_params[name] = value;
331
			this.suo.setPostParams( this.suo.settings.post_params );
332
		}
333
 
334
	, stopUpload: function( cancel_btn ) {
335
			this.suo.stopUpload();
336
			this.getStore().each(function() {
337
				if (this.data.status == 1) {
338
					this.set('status', 0);
339
					this.commit();
340
				}
341
			});
342
 
343
			this.getTopToolbar().items.get(2).setVisible(false);
344
			this.progress_bar.reset();
345
			this.progress_bar.updateText('Progress Bar');
346
 
347
		}
348
 
349
	, fileCancelled: function(file, code, b, c, d) {
350
			if (code == -280) return;
351
 
352
			this.store.getById(file.id).set('status', 4);
353
			this.store.getById(file.id).commit();
354
			this.progress_bar.reset();
355
			this.progress_bar.updateText('Progress Bar');
356
 
357
			if (this.suo.getStats().files_queued > 0) {
358
				this.getTopToolbar().items.get(2).setVisible(false);
359
			} else {
360
				this.getTopToolbar().items.get(2).setVisible(false);
361
				this.getTopToolbar().items.get(3).setVisible(false);
362
			}
363
 
364
			this.cancelled = true;
365
		}
366
 
367
	, swfUploadLoaded: function() {
368
			this.fireEvent('swfUploadLoaded', this);
369
		}
370
 
371
});