0
|
1 /*
|
|
2 * jQuery File Upload User Interface Plugin 6.9.1
|
|
3 * https://github.com/blueimp/jQuery-File-Upload
|
|
4 *
|
|
5 * Copyright 2010, Sebastian Tschan
|
|
6 * https://blueimp.net
|
|
7 *
|
|
8 * Licensed under the MIT license:
|
|
9 * http://www.opensource.org/licenses/MIT
|
|
10 */
|
|
11
|
|
12 /*jslint nomen: true, unparam: true, regexp: true */
|
|
13 /*global define, window, document, URL, webkitURL, FileReader */
|
|
14
|
|
15 (function (factory) {
|
|
16 'use strict';
|
|
17 if (typeof define === 'function' && define.amd) {
|
|
18 // Register as an anonymous AMD module:
|
|
19 define([
|
|
20 'jquery',
|
|
21 'tmpl',
|
|
22 'load-image',
|
|
23 './jquery.fileupload-fp'
|
|
24 ], factory);
|
|
25 } else {
|
|
26 // Browser globals:
|
|
27 factory(
|
|
28 window.jQuery,
|
|
29 window.tmpl,
|
|
30 window.loadImage
|
|
31 );
|
|
32 }
|
|
33 }(function ($, tmpl, loadImage) {
|
|
34 'use strict';
|
|
35
|
|
36 // The UI version extends the FP (file processing) version or the basic
|
|
37 // file upload widget and adds complete user interface interaction:
|
|
38 var parentWidget = ($.blueimpFP || $.blueimp).fileupload;
|
|
39 $.widget('blueimpUI.fileupload', parentWidget, {
|
|
40
|
|
41 options: {
|
|
42 // By default, files added to the widget are uploaded as soon
|
|
43 // as the user clicks on the start buttons. To enable automatic
|
|
44 // uploads, set the following option to true:
|
|
45 autoUpload: false,
|
|
46 // The following option limits the number of files that are
|
|
47 // allowed to be uploaded using this widget:
|
|
48 maxNumberOfFiles: undefined,
|
|
49 // The maximum allowed file size:
|
|
50 maxFileSize: undefined,
|
|
51 // The minimum allowed file size:
|
|
52 minFileSize: undefined,
|
|
53 // The regular expression for allowed file types, matches
|
|
54 // against either file type or file name:
|
|
55 acceptFileTypes: /.+$/i,
|
|
56 // The regular expression to define for which files a preview
|
|
57 // image is shown, matched against the file type:
|
|
58 previewSourceFileTypes: /^image\/(gif|jpeg|png)$/,
|
|
59 // The maximum file size of images that are to be displayed as preview:
|
|
60 previewSourceMaxFileSize: 5000000, // 5MB
|
|
61 // The maximum width of the preview images:
|
|
62 previewMaxWidth: 80,
|
|
63 // The maximum height of the preview images:
|
|
64 previewMaxHeight: 80,
|
|
65 // By default, preview images are displayed as canvas elements
|
|
66 // if supported by the browser. Set the following option to false
|
|
67 // to always display preview images as img elements:
|
|
68 previewAsCanvas: true,
|
|
69 // The ID of the upload template:
|
|
70 uploadTemplateId: 'template-upload',
|
|
71 // The ID of the download template:
|
|
72 downloadTemplateId: 'template-download',
|
|
73 // The container for the list of files. If undefined, it is set to
|
|
74 // an element with class "files" inside of the widget element:
|
|
75 filesContainer: undefined,
|
|
76 // By default, files are appended to the files container.
|
|
77 // Set the following option to true, to prepend files instead:
|
|
78 prependFiles: false,
|
|
79 // The expected data type of the upload response, sets the dataType
|
|
80 // option of the $.ajax upload requests:
|
|
81 dataType: 'json',
|
|
82
|
|
83 // The add callback is invoked as soon as files are added to the fileupload
|
|
84 // widget (via file input selection, drag & drop or add API call).
|
|
85 // See the basic file upload widget for more information:
|
|
86 add: function (e, data) {
|
|
87 var that = $(this).data('fileupload'),
|
|
88 options = that.options,
|
|
89 files = data.files;
|
|
90 $(this).fileupload('process', data).done(function () {
|
|
91 that._adjustMaxNumberOfFiles(-files.length);
|
|
92 data.isAdjusted = true;
|
|
93 data.files.valid = data.isValidated = that._validate(files);
|
|
94 data.context = that._renderUpload(files).data('data', data);
|
|
95 options.filesContainer[
|
|
96 options.prependFiles ? 'prepend' : 'append'
|
|
97 ](data.context);
|
|
98 that._renderPreviews(files, data.context);
|
|
99 that._forceReflow(data.context);
|
|
100 that._transition(data.context).done(
|
|
101 function () {
|
|
102 if ((that._trigger('added', e, data) !== false) &&
|
|
103 (options.autoUpload || data.autoUpload) &&
|
|
104 data.autoUpload !== false && data.isValidated) {
|
|
105 data.submit();
|
|
106 }
|
|
107 }
|
|
108 );
|
|
109 });
|
|
110 },
|
|
111 // Callback for the start of each file upload request:
|
|
112 send: function (e, data) {
|
|
113 var that = $(this).data('fileupload');
|
|
114 if (!data.isValidated) {
|
|
115 if (!data.isAdjusted) {
|
|
116 that._adjustMaxNumberOfFiles(-data.files.length);
|
|
117 }
|
|
118 if (!that._validate(data.files)) {
|
|
119 return false;
|
|
120 }
|
|
121 }
|
|
122 if (data.context && data.dataType &&
|
|
123 data.dataType.substr(0, 6) === 'iframe') {
|
|
124 // Iframe Transport does not support progress events.
|
|
125 // In lack of an indeterminate progress bar, we set
|
|
126 // the progress to 100%, showing the full animated bar:
|
|
127 data.context
|
|
128 .find('.progress').addClass(
|
|
129 !$.support.transition && 'progress-animated'
|
|
130 )
|
|
131 .attr('aria-valuenow', 100)
|
|
132 .find('.bar').css(
|
|
133 'width',
|
|
134 '100%'
|
|
135 );
|
|
136 }
|
|
137 return that._trigger('sent', e, data);
|
|
138 },
|
|
139 // Callback for successful uploads:
|
|
140 done: function (e, data) {
|
|
141 var that = $(this).data('fileupload'),
|
|
142 template;
|
|
143 if (data.context) {
|
|
144 data.context.each(function (index) {
|
|
145 var file = ($.isArray(data.result) &&
|
|
146 data.result[index]) || {error: 'emptyResult'};
|
|
147 if (file.error) {
|
|
148 that._adjustMaxNumberOfFiles(1);
|
|
149 }
|
|
150 that._transition($(this)).done(
|
|
151 function () {
|
|
152 var node = $(this);
|
|
153 template = that._renderDownload([file])
|
|
154 .css('height', node.height())
|
|
155 .replaceAll(node);
|
|
156 that._forceReflow(template);
|
|
157 that._transition(template).done(
|
|
158 function () {
|
|
159 data.context = $(this);
|
|
160 that._trigger('completed', e, data);
|
|
161 }
|
|
162 );
|
|
163 }
|
|
164 );
|
|
165 });
|
|
166 } else {
|
|
167 template = that._renderDownload(data.result)
|
|
168 .appendTo(that.options.filesContainer);
|
|
169 that._forceReflow(template);
|
|
170 that._transition(template).done(
|
|
171 function () {
|
|
172 data.context = $(this);
|
|
173 that._trigger('completed', e, data);
|
|
174 }
|
|
175 );
|
|
176 }
|
|
177 },
|
|
178 // Callback for failed (abort or error) uploads:
|
|
179 fail: function (e, data) {
|
|
180 var that = $(this).data('fileupload'),
|
|
181 template;
|
|
182 that._adjustMaxNumberOfFiles(data.files.length);
|
|
183 if (data.context) {
|
|
184 data.context.each(function (index) {
|
|
185 if (data.errorThrown !== 'abort') {
|
|
186 var file = data.files[index];
|
|
187 file.error = file.error || data.errorThrown ||
|
|
188 true;
|
|
189 that._transition($(this)).done(
|
|
190 function () {
|
|
191 var node = $(this);
|
|
192 template = that._renderDownload([file])
|
|
193 .replaceAll(node);
|
|
194 that._forceReflow(template);
|
|
195 that._transition(template).done(
|
|
196 function () {
|
|
197 data.context = $(this);
|
|
198 that._trigger('failed', e, data);
|
|
199 }
|
|
200 );
|
|
201 }
|
|
202 );
|
|
203 } else {
|
|
204 that._transition($(this)).done(
|
|
205 function () {
|
|
206 $(this).remove();
|
|
207 that._trigger('failed', e, data);
|
|
208 }
|
|
209 );
|
|
210 }
|
|
211 });
|
|
212 } else if (data.errorThrown !== 'abort') {
|
|
213 that._adjustMaxNumberOfFiles(-data.files.length);
|
|
214 data.context = that._renderUpload(data.files)
|
|
215 .appendTo(that.options.filesContainer)
|
|
216 .data('data', data);
|
|
217 that._forceReflow(data.context);
|
|
218 that._transition(data.context).done(
|
|
219 function () {
|
|
220 data.context = $(this);
|
|
221 that._trigger('failed', e, data);
|
|
222 }
|
|
223 );
|
|
224 } else {
|
|
225 that._trigger('failed', e, data);
|
|
226 }
|
|
227 },
|
|
228 // Callback for upload progress events:
|
|
229 progress: function (e, data) {
|
|
230 if (data.context) {
|
|
231 var progress = parseInt(data.loaded / data.total * 100, 10);
|
|
232 data.context.find('.progress')
|
|
233 .attr('aria-valuenow', progress)
|
|
234 .find('.bar').css(
|
|
235 'width',
|
|
236 progress + '%'
|
|
237 );
|
|
238 }
|
|
239 },
|
|
240 // Callback for global upload progress events:
|
|
241 progressall: function (e, data) {
|
|
242 var $this = $(this),
|
|
243 progress = parseInt(data.loaded / data.total * 100, 10),
|
|
244 globalProgressNode = $this.find('.fileupload-progress'),
|
|
245 extendedProgressNode = globalProgressNode
|
|
246 .find('.progress-extended');
|
|
247 if (extendedProgressNode.length) {
|
|
248 extendedProgressNode.html(
|
|
249 $this.data('fileupload')._renderExtendedProgress(data)
|
|
250 );
|
|
251 }
|
|
252 globalProgressNode
|
|
253 .find('.progress')
|
|
254 .attr('aria-valuenow', progress)
|
|
255 .find('.bar').css(
|
|
256 'width',
|
|
257 progress + '%'
|
|
258 );
|
|
259 },
|
|
260 // Callback for uploads start, equivalent to the global ajaxStart event:
|
|
261 start: function (e) {
|
|
262 var that = $(this).data('fileupload');
|
|
263 that._transition($(this).find('.fileupload-progress')).done(
|
|
264 function () {
|
|
265 that._trigger('started', e);
|
|
266 }
|
|
267 );
|
|
268 },
|
|
269 // Callback for uploads stop, equivalent to the global ajaxStop event:
|
|
270 stop: function (e) {
|
|
271 var that = $(this).data('fileupload');
|
|
272 that._transition($(this).find('.fileupload-progress')).done(
|
|
273 function () {
|
|
274 $(this).find('.progress')
|
|
275 .attr('aria-valuenow', '0')
|
|
276 .find('.bar').css('width', '0%');
|
|
277 $(this).find('.progress-extended').html(' ');
|
|
278 that._trigger('stopped', e);
|
|
279 }
|
|
280 );
|
|
281 },
|
|
282 // Callback for file deletion:
|
|
283 destroy: function (e, data) {
|
|
284 var that = $(this).data('fileupload');
|
|
285 if (data.url) {
|
|
286 $.ajax(data);
|
|
287 that._adjustMaxNumberOfFiles(1);
|
|
288 }
|
|
289 that._transition(data.context).done(
|
|
290 function () {
|
|
291 $(this).remove();
|
|
292 that._trigger('destroyed', e, data);
|
|
293 }
|
|
294 );
|
|
295 }
|
|
296 },
|
|
297
|
|
298 // Link handler, that allows to download files
|
|
299 // by drag & drop of the links to the desktop:
|
|
300 _enableDragToDesktop: function () {
|
|
301 var link = $(this),
|
|
302 url = link.prop('href'),
|
|
303 name = link.prop('download'),
|
|
304 type = 'application/octet-stream';
|
|
305 link.bind('dragstart', function (e) {
|
|
306 try {
|
|
307 e.originalEvent.dataTransfer.setData(
|
|
308 'DownloadURL',
|
|
309 [type, name, url].join(':')
|
|
310 );
|
|
311 } catch (err) {}
|
|
312 });
|
|
313 },
|
|
314
|
|
315 _adjustMaxNumberOfFiles: function (operand) {
|
|
316 if (typeof this.options.maxNumberOfFiles === 'number') {
|
|
317 this.options.maxNumberOfFiles += operand;
|
|
318 if (this.options.maxNumberOfFiles < 1) {
|
|
319 this._disableFileInputButton();
|
|
320 } else {
|
|
321 this._enableFileInputButton();
|
|
322 }
|
|
323 }
|
|
324 },
|
|
325
|
|
326 _formatFileSize: function (bytes) {
|
|
327 if (typeof bytes !== 'number') {
|
|
328 return '';
|
|
329 }
|
|
330 if (bytes >= 1000000000) {
|
|
331 return (bytes / 1000000000).toFixed(2) + ' GB';
|
|
332 }
|
|
333 if (bytes >= 1000000) {
|
|
334 return (bytes / 1000000).toFixed(2) + ' MB';
|
|
335 }
|
|
336 return (bytes / 1000).toFixed(2) + ' KB';
|
|
337 },
|
|
338
|
|
339 _formatBitrate: function (bits) {
|
|
340 if (typeof bits !== 'number') {
|
|
341 return '';
|
|
342 }
|
|
343 if (bits >= 1000000000) {
|
|
344 return (bits / 1000000000).toFixed(2) + ' Gbit/s';
|
|
345 }
|
|
346 if (bits >= 1000000) {
|
|
347 return (bits / 1000000).toFixed(2) + ' Mbit/s';
|
|
348 }
|
|
349 if (bits >= 1000) {
|
|
350 return (bits / 1000).toFixed(2) + ' kbit/s';
|
|
351 }
|
|
352 return bits + ' bit/s';
|
|
353 },
|
|
354
|
|
355 _formatTime: function (seconds) {
|
|
356 var date = new Date(seconds * 1000),
|
|
357 days = parseInt(seconds / 86400, 10);
|
|
358 days = days ? days + 'd ' : '';
|
|
359 return days +
|
|
360 ('0' + date.getUTCHours()).slice(-2) + ':' +
|
|
361 ('0' + date.getUTCMinutes()).slice(-2) + ':' +
|
|
362 ('0' + date.getUTCSeconds()).slice(-2);
|
|
363 },
|
|
364
|
|
365 _formatPercentage: function (floatValue) {
|
|
366 return (floatValue * 100).toFixed(2) + ' %';
|
|
367 },
|
|
368
|
|
369 _renderExtendedProgress: function (data) {
|
|
370 return this._formatBitrate(data.bitrate) + ' | ' +
|
|
371 this._formatTime(
|
|
372 (data.total - data.loaded) * 8 / data.bitrate
|
|
373 ) + ' | ' +
|
|
374 this._formatPercentage(
|
|
375 data.loaded / data.total
|
|
376 ) + ' | ' +
|
|
377 this._formatFileSize(data.loaded) + ' / ' +
|
|
378 this._formatFileSize(data.total);
|
|
379 },
|
|
380
|
|
381 _hasError: function (file) {
|
|
382 if (file.error) {
|
|
383 return file.error;
|
|
384 }
|
|
385 // The number of added files is subtracted from
|
|
386 // maxNumberOfFiles before validation, so we check if
|
|
387 // maxNumberOfFiles is below 0 (instead of below 1):
|
|
388 if (this.options.maxNumberOfFiles < 0) {
|
|
389 return 'maxNumberOfFiles';
|
|
390 }
|
|
391 // Files are accepted if either the file type or the file name
|
|
392 // matches against the acceptFileTypes regular expression, as
|
|
393 // only browsers with support for the File API report the type:
|
|
394 if (!(this.options.acceptFileTypes.test(file.type) ||
|
|
395 this.options.acceptFileTypes.test(file.name))) {
|
|
396 return 'acceptFileTypes';
|
|
397 }
|
|
398 if (this.options.maxFileSize &&
|
|
399 file.size > this.options.maxFileSize) {
|
|
400 return 'maxFileSize';
|
|
401 }
|
|
402 if (typeof file.size === 'number' &&
|
|
403 file.size < this.options.minFileSize) {
|
|
404 return 'minFileSize';
|
|
405 }
|
|
406 return null;
|
|
407 },
|
|
408
|
|
409 _validate: function (files) {
|
|
410 var that = this,
|
|
411 valid = !!files.length;
|
|
412 $.each(files, function (index, file) {
|
|
413 file.error = that._hasError(file);
|
|
414 if (file.error) {
|
|
415 valid = false;
|
|
416 }
|
|
417 });
|
|
418 return valid;
|
|
419 },
|
|
420
|
|
421 _renderTemplate: function (func, files) {
|
|
422 if (!func) {
|
|
423 return $();
|
|
424 }
|
|
425 var result = func({
|
|
426 files: files,
|
|
427 formatFileSize: this._formatFileSize,
|
|
428 options: this.options
|
|
429 });
|
|
430 if (result instanceof $) {
|
|
431 return result;
|
|
432 }
|
|
433 return $(this.options.templatesContainer).html(result).children();
|
|
434 },
|
|
435
|
|
436 _renderPreview: function (file, node) {
|
|
437 var that = this,
|
|
438 options = this.options,
|
|
439 dfd = $.Deferred();
|
|
440 return ((loadImage && loadImage(
|
|
441 file,
|
|
442 function (img) {
|
|
443 node.append(img);
|
|
444 that._forceReflow(node);
|
|
445 that._transition(node).done(function () {
|
|
446 dfd.resolveWith(node);
|
|
447 });
|
|
448 if (!$.contains(document.body, node[0])) {
|
|
449 // If the element is not part of the DOM,
|
|
450 // transition events are not triggered,
|
|
451 // so we have to resolve manually:
|
|
452 dfd.resolveWith(node);
|
|
453 }
|
|
454 },
|
|
455 {
|
|
456 maxWidth: options.previewMaxWidth,
|
|
457 maxHeight: options.previewMaxHeight,
|
|
458 canvas: options.previewAsCanvas
|
|
459 }
|
|
460 )) || dfd.resolveWith(node)) && dfd;
|
|
461 },
|
|
462
|
|
463 _renderPreviews: function (files, nodes) {
|
|
464 var that = this,
|
|
465 options = this.options;
|
|
466 nodes.find('.preview span').each(function (index, element) {
|
|
467 var file = files[index];
|
|
468 if (options.previewSourceFileTypes.test(file.type) &&
|
|
469 ($.type(options.previewSourceMaxFileSize) !== 'number' ||
|
|
470 file.size < options.previewSourceMaxFileSize)) {
|
|
471 that._processingQueue = that._processingQueue.pipe(function () {
|
|
472 var dfd = $.Deferred();
|
|
473 that._renderPreview(file, $(element)).done(
|
|
474 function () {
|
|
475 dfd.resolveWith(that);
|
|
476 }
|
|
477 );
|
|
478 return dfd.promise();
|
|
479 });
|
|
480 }
|
|
481 });
|
|
482 return this._processingQueue;
|
|
483 },
|
|
484
|
|
485 _renderUpload: function (files) {
|
|
486 return this._renderTemplate(
|
|
487 this.options.uploadTemplate,
|
|
488 files
|
|
489 );
|
|
490 },
|
|
491
|
|
492 _renderDownload: function (files) {
|
|
493 return this._renderTemplate(
|
|
494 this.options.downloadTemplate,
|
|
495 files
|
|
496 ).find('a[download]').each(this._enableDragToDesktop).end();
|
|
497 },
|
|
498
|
|
499 _startHandler: function (e) {
|
|
500 e.preventDefault();
|
|
501 var button = $(this),
|
|
502 template = button.closest('.template-upload'),
|
|
503 data = template.data('data');
|
|
504 if (data && data.submit && !data.jqXHR && data.submit()) {
|
|
505 button.prop('disabled', true);
|
|
506 }
|
|
507 },
|
|
508
|
|
509 _cancelHandler: function (e) {
|
|
510 e.preventDefault();
|
|
511 var template = $(this).closest('.template-upload'),
|
|
512 data = template.data('data') || {};
|
|
513 if (!data.jqXHR) {
|
|
514 data.errorThrown = 'abort';
|
|
515 e.data.fileupload._trigger('fail', e, data);
|
|
516 } else {
|
|
517 data.jqXHR.abort();
|
|
518 }
|
|
519 },
|
|
520
|
|
521 _deleteHandler: function (e) {
|
|
522 e.preventDefault();
|
|
523 var button = $(this);
|
|
524 e.data.fileupload._trigger('destroy', e, {
|
|
525 context: button.closest('.template-download'),
|
|
526 url: button.attr('data-url'),
|
|
527 type: button.attr('data-type') || 'DELETE',
|
|
528 dataType: e.data.fileupload.options.dataType
|
|
529 });
|
|
530 },
|
|
531
|
|
532 _forceReflow: function (node) {
|
|
533 return $.support.transition && node.length &&
|
|
534 node[0].offsetWidth;
|
|
535 },
|
|
536
|
|
537 _transition: function (node) {
|
|
538 var dfd = $.Deferred();
|
|
539 if ($.support.transition && node.hasClass('fade')) {
|
|
540 node.bind(
|
|
541 $.support.transition.end,
|
|
542 function (e) {
|
|
543 // Make sure we don't respond to other transitions events
|
|
544 // in the container element, e.g. from button elements:
|
|
545 if (e.target === node[0]) {
|
|
546 node.unbind($.support.transition.end);
|
|
547 dfd.resolveWith(node);
|
|
548 }
|
|
549 }
|
|
550 ).toggleClass('in');
|
|
551 } else {
|
|
552 node.toggleClass('in');
|
|
553 dfd.resolveWith(node);
|
|
554 }
|
|
555 return dfd;
|
|
556 },
|
|
557
|
|
558 _initButtonBarEventHandlers: function () {
|
|
559 var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
|
|
560 filesList = this.options.filesContainer,
|
|
561 ns = this.options.namespace;
|
|
562 fileUploadButtonBar.find('.start')
|
|
563 .bind('click.' + ns, function (e) {
|
|
564 e.preventDefault();
|
|
565 filesList.find('.start button').click();
|
|
566 });
|
|
567 fileUploadButtonBar.find('.cancel')
|
|
568 .bind('click.' + ns, function (e) {
|
|
569 e.preventDefault();
|
|
570 filesList.find('.cancel button').click();
|
|
571 });
|
|
572 fileUploadButtonBar.find('.delete')
|
|
573 .bind('click.' + ns, function (e) {
|
|
574 e.preventDefault();
|
|
575 filesList.find('.delete input:checked')
|
|
576 .siblings('button').click();
|
|
577 fileUploadButtonBar.find('.toggle')
|
|
578 .prop('checked', false);
|
|
579 });
|
|
580 fileUploadButtonBar.find('.toggle')
|
|
581 .bind('change.' + ns, function (e) {
|
|
582 filesList.find('.delete input').prop(
|
|
583 'checked',
|
|
584 $(this).is(':checked')
|
|
585 );
|
|
586 });
|
|
587 },
|
|
588
|
|
589 _destroyButtonBarEventHandlers: function () {
|
|
590 this.element.find('.fileupload-buttonbar button')
|
|
591 .unbind('click.' + this.options.namespace);
|
|
592 this.element.find('.fileupload-buttonbar .toggle')
|
|
593 .unbind('change.' + this.options.namespace);
|
|
594 },
|
|
595
|
|
596 _initEventHandlers: function () {
|
|
597 parentWidget.prototype._initEventHandlers.call(this);
|
|
598 var eventData = {fileupload: this};
|
|
599 this.options.filesContainer
|
|
600 .delegate(
|
|
601 '.start button',
|
|
602 'click.' + this.options.namespace,
|
|
603 eventData,
|
|
604 this._startHandler
|
|
605 )
|
|
606 .delegate(
|
|
607 '.cancel button',
|
|
608 'click.' + this.options.namespace,
|
|
609 eventData,
|
|
610 this._cancelHandler
|
|
611 )
|
|
612 .delegate(
|
|
613 '.delete button',
|
|
614 'click.' + this.options.namespace,
|
|
615 eventData,
|
|
616 this._deleteHandler
|
|
617 );
|
|
618 this._initButtonBarEventHandlers();
|
|
619 },
|
|
620
|
|
621 _destroyEventHandlers: function () {
|
|
622 var options = this.options;
|
|
623 this._destroyButtonBarEventHandlers();
|
|
624 options.filesContainer
|
|
625 .undelegate('.start button', 'click.' + options.namespace)
|
|
626 .undelegate('.cancel button', 'click.' + options.namespace)
|
|
627 .undelegate('.delete button', 'click.' + options.namespace);
|
|
628 parentWidget.prototype._destroyEventHandlers.call(this);
|
|
629 },
|
|
630
|
|
631 _enableFileInputButton: function () {
|
|
632 this.element.find('.fileinput-button input')
|
|
633 .prop('disabled', false)
|
|
634 .parent().removeClass('disabled');
|
|
635 },
|
|
636
|
|
637 _disableFileInputButton: function () {
|
|
638 this.element.find('.fileinput-button input')
|
|
639 .prop('disabled', true)
|
|
640 .parent().addClass('disabled');
|
|
641 },
|
|
642
|
|
643 _initTemplates: function () {
|
|
644 var options = this.options;
|
|
645 options.templatesContainer = document.createElement(
|
|
646 options.filesContainer.prop('nodeName')
|
|
647 );
|
|
648 if (tmpl) {
|
|
649 if (options.uploadTemplateId) {
|
|
650 options.uploadTemplate = tmpl(options.uploadTemplateId);
|
|
651 }
|
|
652 if (options.downloadTemplateId) {
|
|
653 options.downloadTemplate = tmpl(options.downloadTemplateId);
|
|
654 }
|
|
655 }
|
|
656 },
|
|
657
|
|
658 _initFilesContainer: function () {
|
|
659 var options = this.options;
|
|
660 if (options.filesContainer === undefined) {
|
|
661 options.filesContainer = this.element.find('.files');
|
|
662 } else if (!(options.filesContainer instanceof $)) {
|
|
663 options.filesContainer = $(options.filesContainer);
|
|
664 }
|
|
665 },
|
|
666
|
|
667 _initSpecialOptions: function () {
|
|
668 parentWidget.prototype._initSpecialOptions.call(this);
|
|
669 this._initFilesContainer();
|
|
670 this._initTemplates();
|
|
671 },
|
|
672
|
|
673 _create: function () {
|
|
674 parentWidget.prototype._create.call(this);
|
|
675 this._refreshOptionsList.push(
|
|
676 'filesContainer',
|
|
677 'uploadTemplateId',
|
|
678 'downloadTemplateId'
|
|
679 );
|
|
680 if (!$.blueimpFP) {
|
|
681 this._processingQueue = $.Deferred().resolveWith(this).promise();
|
|
682 this.process = function () {
|
|
683 return this._processingQueue;
|
|
684 };
|
|
685 }
|
|
686 },
|
|
687
|
|
688 enable: function () {
|
|
689 parentWidget.prototype.enable.call(this);
|
|
690 this.element.find('input, button').prop('disabled', false);
|
|
691 this._enableFileInputButton();
|
|
692 },
|
|
693
|
|
694 disable: function () {
|
|
695 this.element.find('input, button').prop('disabled', true);
|
|
696 this._disableFileInputButton();
|
|
697 parentWidget.prototype.disable.call(this);
|
|
698 }
|
|
699
|
|
700 });
|
|
701
|
|
702 }));
|