1 | /* |
---|
2 | * jQuery File Upload User Interface Plugin 8.7.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, 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 | './jquery.fileupload-image', |
---|
23 | './jquery.fileupload-audio', |
---|
24 | './jquery.fileupload-video', |
---|
25 | './jquery.fileupload-validate' |
---|
26 | ], factory); |
---|
27 | } else { |
---|
28 | // Browser globals: |
---|
29 | factory( |
---|
30 | window.jQuery, |
---|
31 | window.tmpl |
---|
32 | ); |
---|
33 | } |
---|
34 | }(function ($, tmpl, loadImage) { |
---|
35 | 'use strict'; |
---|
36 | |
---|
37 | $.blueimp.fileupload.prototype._specialOptions.push( |
---|
38 | 'filesContainer', |
---|
39 | 'uploadTemplateId', |
---|
40 | 'downloadTemplateId' |
---|
41 | ); |
---|
42 | |
---|
43 | // The UI version extends the file upload widget |
---|
44 | // and adds complete user interface interaction: |
---|
45 | $.widget('blueimp.fileupload', $.blueimp.fileupload, { |
---|
46 | |
---|
47 | options: { |
---|
48 | // By default, files added to the widget are uploaded as soon |
---|
49 | // as the user clicks on the start buttons. To enable automatic |
---|
50 | // uploads, set the following option to true: |
---|
51 | autoUpload: false, |
---|
52 | // The ID of the upload template: |
---|
53 | uploadTemplateId: 'template-upload', |
---|
54 | // The ID of the download template: |
---|
55 | downloadTemplateId: 'template-download', |
---|
56 | // The container for the list of files. If undefined, it is set to |
---|
57 | // an element with class "files" inside of the widget element: |
---|
58 | filesContainer: undefined, |
---|
59 | // By default, files are appended to the files container. |
---|
60 | // Set the following option to true, to prepend files instead: |
---|
61 | prependFiles: false, |
---|
62 | // The expected data type of the upload response, sets the dataType |
---|
63 | // option of the $.ajax upload requests: |
---|
64 | dataType: 'json', |
---|
65 | |
---|
66 | // Function returning the current number of files, |
---|
67 | // used by the maxNumberOfFiles validation: |
---|
68 | getNumberOfFiles: function () { |
---|
69 | return this.filesContainer.children().length; |
---|
70 | }, |
---|
71 | |
---|
72 | // Callback to retrieve the list of files from the server response: |
---|
73 | getFilesFromResponse: function (data) { |
---|
74 | if (data.result && $.isArray(data.result.files)) { |
---|
75 | return data.result.files; |
---|
76 | } |
---|
77 | return []; |
---|
78 | }, |
---|
79 | |
---|
80 | // The add callback is invoked as soon as files are added to the fileupload |
---|
81 | // widget (via file input selection, drag & drop or add API call). |
---|
82 | // See the basic file upload widget for more information: |
---|
83 | add: function (e, data) { |
---|
84 | var $this = $(this), |
---|
85 | that = $this.data('blueimp-fileupload') || |
---|
86 | $this.data('fileupload'), |
---|
87 | options = that.options, |
---|
88 | files = data.files; |
---|
89 | data.process(function () { |
---|
90 | return $this.fileupload('process', data); |
---|
91 | }).always(function () { |
---|
92 | data.context = that._renderUpload(files).data('data', data); |
---|
93 | that._renderPreviews(data); |
---|
94 | options.filesContainer[ |
---|
95 | options.prependFiles ? 'prepend' : 'append' |
---|
96 | ](data.context); |
---|
97 | that._forceReflow(data.context); |
---|
98 | that._transition(data.context).done( |
---|
99 | function () { |
---|
100 | if ((that._trigger('added', e, data) !== false) && |
---|
101 | (options.autoUpload || data.autoUpload) && |
---|
102 | data.autoUpload !== false && !data.files.error) { |
---|
103 | data.submit(); |
---|
104 | } |
---|
105 | } |
---|
106 | ); |
---|
107 | }); |
---|
108 | }, |
---|
109 | // Callback for the start of each file upload request: |
---|
110 | send: function (e, data) { |
---|
111 | var that = $(this).data('blueimp-fileupload') || |
---|
112 | $(this).data('fileupload'); |
---|
113 | if (data.context && data.dataType && |
---|
114 | data.dataType.substr(0, 6) === 'iframe') { |
---|
115 | // Iframe Transport does not support progress events. |
---|
116 | // In lack of an indeterminate progress bar, we set |
---|
117 | // the progress to 100%, showing the full animated bar: |
---|
118 | data.context |
---|
119 | .find('.progress').addClass( |
---|
120 | !$.support.transition && 'progress-animated' |
---|
121 | ) |
---|
122 | .attr('aria-valuenow', 100) |
---|
123 | .find('.bar').css( |
---|
124 | 'width', |
---|
125 | '100%' |
---|
126 | ); |
---|
127 | } |
---|
128 | return that._trigger('sent', e, data); |
---|
129 | }, |
---|
130 | // Callback for successful uploads: |
---|
131 | done: function (e, data) { |
---|
132 | var that = $(this).data('blueimp-fileupload') || |
---|
133 | $(this).data('fileupload'), |
---|
134 | getFilesFromResponse = data.getFilesFromResponse || |
---|
135 | that.options.getFilesFromResponse, |
---|
136 | files = getFilesFromResponse(data), |
---|
137 | template, |
---|
138 | deferred; |
---|
139 | if (data.context) { |
---|
140 | data.context.each(function (index) { |
---|
141 | var file = files[index] || |
---|
142 | {error: 'Empty file upload result'}; |
---|
143 | deferred = that._addFinishedDeferreds(); |
---|
144 | that._transition($(this)).done( |
---|
145 | function () { |
---|
146 | var node = $(this); |
---|
147 | template = that._renderDownload([file]) |
---|
148 | .replaceAll(node); |
---|
149 | that._forceReflow(template); |
---|
150 | that._transition(template).done( |
---|
151 | function () { |
---|
152 | data.context = $(this); |
---|
153 | that._trigger('completed', e, data); |
---|
154 | that._trigger('finished', e, data); |
---|
155 | deferred.resolve(); |
---|
156 | } |
---|
157 | ); |
---|
158 | } |
---|
159 | ); |
---|
160 | }); |
---|
161 | } else { |
---|
162 | template = that._renderDownload(files)[ |
---|
163 | that.options.prependFiles ? 'prependTo' : 'appendTo' |
---|
164 | ](that.options.filesContainer); |
---|
165 | that._forceReflow(template); |
---|
166 | deferred = that._addFinishedDeferreds(); |
---|
167 | that._transition(template).done( |
---|
168 | function () { |
---|
169 | data.context = $(this); |
---|
170 | that._trigger('completed', e, data); |
---|
171 | that._trigger('finished', e, data); |
---|
172 | deferred.resolve(); |
---|
173 | } |
---|
174 | ); |
---|
175 | } |
---|
176 | }, |
---|
177 | // Callback for failed (abort or error) uploads: |
---|
178 | fail: function (e, data) { |
---|
179 | var that = $(this).data('blueimp-fileupload') || |
---|
180 | $(this).data('fileupload'), |
---|
181 | template, |
---|
182 | deferred; |
---|
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 | deferred = that._addFinishedDeferreds(); |
---|
190 | that._transition($(this)).done( |
---|
191 | function () { |
---|
192 | var node = $(this); |
---|
193 | template = that._renderDownload([file]) |
---|
194 | .replaceAll(node); |
---|
195 | that._forceReflow(template); |
---|
196 | that._transition(template).done( |
---|
197 | function () { |
---|
198 | data.context = $(this); |
---|
199 | that._trigger('failed', e, data); |
---|
200 | that._trigger('finished', e, data); |
---|
201 | deferred.resolve(); |
---|
202 | } |
---|
203 | ); |
---|
204 | } |
---|
205 | ); |
---|
206 | } else { |
---|
207 | deferred = that._addFinishedDeferreds(); |
---|
208 | that._transition($(this)).done( |
---|
209 | function () { |
---|
210 | $(this).remove(); |
---|
211 | that._trigger('failed', e, data); |
---|
212 | that._trigger('finished', e, data); |
---|
213 | deferred.resolve(); |
---|
214 | } |
---|
215 | ); |
---|
216 | } |
---|
217 | }); |
---|
218 | } else if (data.errorThrown !== 'abort') { |
---|
219 | data.context = that._renderUpload(data.files)[ |
---|
220 | that.options.prependFiles ? 'prependTo' : 'appendTo' |
---|
221 | ](that.options.filesContainer) |
---|
222 | .data('data', data); |
---|
223 | that._forceReflow(data.context); |
---|
224 | deferred = that._addFinishedDeferreds(); |
---|
225 | that._transition(data.context).done( |
---|
226 | function () { |
---|
227 | data.context = $(this); |
---|
228 | that._trigger('failed', e, data); |
---|
229 | that._trigger('finished', e, data); |
---|
230 | deferred.resolve(); |
---|
231 | } |
---|
232 | ); |
---|
233 | } else { |
---|
234 | that._trigger('failed', e, data); |
---|
235 | that._trigger('finished', e, data); |
---|
236 | that._addFinishedDeferreds().resolve(); |
---|
237 | } |
---|
238 | }, |
---|
239 | // Callback for upload progress events: |
---|
240 | progress: function (e, data) { |
---|
241 | if (data.context) { |
---|
242 | var progress = Math.floor(data.loaded / data.total * 100); |
---|
243 | data.context.find('.progress') |
---|
244 | .attr('aria-valuenow', progress) |
---|
245 | .find('.bar').css( |
---|
246 | 'width', |
---|
247 | progress + '%' |
---|
248 | ); |
---|
249 | } |
---|
250 | }, |
---|
251 | // Callback for global upload progress events: |
---|
252 | progressall: function (e, data) { |
---|
253 | var $this = $(this), |
---|
254 | progress = Math.floor(data.loaded / data.total * 100), |
---|
255 | globalProgressNode = $this.find('.fileupload-progress'), |
---|
256 | extendedProgressNode = globalProgressNode |
---|
257 | .find('.progress-extended'); |
---|
258 | if (extendedProgressNode.length) { |
---|
259 | extendedProgressNode.html( |
---|
260 | ($this.data('blueimp-fileupload') || $this.data('fileupload')) |
---|
261 | ._renderExtendedProgress(data) |
---|
262 | ); |
---|
263 | } |
---|
264 | globalProgressNode |
---|
265 | .find('.progress') |
---|
266 | .attr('aria-valuenow', progress) |
---|
267 | .find('.bar').css( |
---|
268 | 'width', |
---|
269 | progress + '%' |
---|
270 | ); |
---|
271 | }, |
---|
272 | // Callback for uploads start, equivalent to the global ajaxStart event: |
---|
273 | start: function (e) { |
---|
274 | var that = $(this).data('blueimp-fileupload') || |
---|
275 | $(this).data('fileupload'); |
---|
276 | that._resetFinishedDeferreds(); |
---|
277 | that._transition($(this).find('.fileupload-progress')).done( |
---|
278 | function () { |
---|
279 | that._trigger('started', e); |
---|
280 | } |
---|
281 | ); |
---|
282 | }, |
---|
283 | // Callback for uploads stop, equivalent to the global ajaxStop event: |
---|
284 | stop: function (e) { |
---|
285 | var that = $(this).data('blueimp-fileupload') || |
---|
286 | $(this).data('fileupload'), |
---|
287 | deferred = that._addFinishedDeferreds(); |
---|
288 | $.when.apply($, that._getFinishedDeferreds()) |
---|
289 | .done(function () { |
---|
290 | that._trigger('stopped', e); |
---|
291 | }); |
---|
292 | that._transition($(this).find('.fileupload-progress')).done( |
---|
293 | function () { |
---|
294 | $(this).find('.progress') |
---|
295 | .attr('aria-valuenow', '0') |
---|
296 | .find('.bar').css('width', '0%'); |
---|
297 | $(this).find('.progress-extended').html(' '); |
---|
298 | deferred.resolve(); |
---|
299 | } |
---|
300 | ); |
---|
301 | }, |
---|
302 | processstart: function () { |
---|
303 | $(this).addClass('fileupload-processing'); |
---|
304 | }, |
---|
305 | processstop: function () { |
---|
306 | $(this).removeClass('fileupload-processing'); |
---|
307 | }, |
---|
308 | // Callback for file deletion: |
---|
309 | destroy: function (e, data) { |
---|
310 | var that = $(this).data('blueimp-fileupload') || |
---|
311 | $(this).data('fileupload'), |
---|
312 | removeNode = function () { |
---|
313 | that._transition(data.context).done( |
---|
314 | function () { |
---|
315 | $(this).remove(); |
---|
316 | that._trigger('destroyed', e, data); |
---|
317 | } |
---|
318 | ); |
---|
319 | }; |
---|
320 | if (data.url) { |
---|
321 | $.ajax(data).done(removeNode); |
---|
322 | } else { |
---|
323 | removeNode(); |
---|
324 | } |
---|
325 | } |
---|
326 | }, |
---|
327 | |
---|
328 | _resetFinishedDeferreds: function () { |
---|
329 | this._finishedUploads = []; |
---|
330 | }, |
---|
331 | |
---|
332 | _addFinishedDeferreds: function (deferred) { |
---|
333 | if (!deferred) { |
---|
334 | deferred = $.Deferred(); |
---|
335 | } |
---|
336 | this._finishedUploads.push(deferred); |
---|
337 | return deferred; |
---|
338 | }, |
---|
339 | |
---|
340 | _getFinishedDeferreds: function () { |
---|
341 | return this._finishedUploads; |
---|
342 | }, |
---|
343 | |
---|
344 | // Link handler, that allows to download files |
---|
345 | // by drag & drop of the links to the desktop: |
---|
346 | _enableDragToDesktop: function () { |
---|
347 | var link = $(this), |
---|
348 | url = link.prop('href'), |
---|
349 | name = link.prop('download'), |
---|
350 | type = 'application/octet-stream'; |
---|
351 | link.bind('dragstart', function (e) { |
---|
352 | try { |
---|
353 | e.originalEvent.dataTransfer.setData( |
---|
354 | 'DownloadURL', |
---|
355 | [type, name, url].join(':') |
---|
356 | ); |
---|
357 | } catch (ignore) {} |
---|
358 | }); |
---|
359 | }, |
---|
360 | |
---|
361 | _formatFileSize: function (bytes) { |
---|
362 | if (typeof bytes !== 'number') { |
---|
363 | return ''; |
---|
364 | } |
---|
365 | if (bytes >= 1000000000) { |
---|
366 | return (bytes / 1000000000).toFixed(2) + ' GB'; |
---|
367 | } |
---|
368 | if (bytes >= 1000000) { |
---|
369 | return (bytes / 1000000).toFixed(2) + ' MB'; |
---|
370 | } |
---|
371 | return (bytes / 1000).toFixed(2) + ' KB'; |
---|
372 | }, |
---|
373 | |
---|
374 | _formatBitrate: function (bits) { |
---|
375 | if (typeof bits !== 'number') { |
---|
376 | return ''; |
---|
377 | } |
---|
378 | if (bits >= 1000000000) { |
---|
379 | return (bits / 1000000000).toFixed(2) + ' Gbit/s'; |
---|
380 | } |
---|
381 | if (bits >= 1000000) { |
---|
382 | return (bits / 1000000).toFixed(2) + ' Mbit/s'; |
---|
383 | } |
---|
384 | if (bits >= 1000) { |
---|
385 | return (bits / 1000).toFixed(2) + ' kbit/s'; |
---|
386 | } |
---|
387 | return bits.toFixed(2) + ' bit/s'; |
---|
388 | }, |
---|
389 | |
---|
390 | _formatTime: function (seconds) { |
---|
391 | var date = new Date(seconds * 1000), |
---|
392 | days = Math.floor(seconds / 86400); |
---|
393 | days = days ? days + 'd ' : ''; |
---|
394 | return days + |
---|
395 | ('0' + date.getUTCHours()).slice(-2) + ':' + |
---|
396 | ('0' + date.getUTCMinutes()).slice(-2) + ':' + |
---|
397 | ('0' + date.getUTCSeconds()).slice(-2); |
---|
398 | }, |
---|
399 | |
---|
400 | _formatPercentage: function (floatValue) { |
---|
401 | return (floatValue * 100).toFixed(2) + ' %'; |
---|
402 | }, |
---|
403 | |
---|
404 | _renderExtendedProgress: function (data) { |
---|
405 | return this._formatBitrate(data.bitrate) + ' | ' + |
---|
406 | this._formatTime( |
---|
407 | (data.total - data.loaded) * 8 / data.bitrate |
---|
408 | ) + ' | ' + |
---|
409 | this._formatPercentage( |
---|
410 | data.loaded / data.total |
---|
411 | ) + ' | ' + |
---|
412 | this._formatFileSize(data.loaded) + ' / ' + |
---|
413 | this._formatFileSize(data.total); |
---|
414 | }, |
---|
415 | |
---|
416 | _renderTemplate: function (func, files) { |
---|
417 | if (!func) { |
---|
418 | return $(); |
---|
419 | } |
---|
420 | var result = func({ |
---|
421 | files: files, |
---|
422 | formatFileSize: this._formatFileSize, |
---|
423 | options: this.options |
---|
424 | }); |
---|
425 | if (result instanceof $) { |
---|
426 | return result; |
---|
427 | } |
---|
428 | return $(this.options.templatesContainer).html(result).children(); |
---|
429 | }, |
---|
430 | |
---|
431 | _renderPreviews: function (data) { |
---|
432 | data.context.find('.preview').each(function (index, elm) { |
---|
433 | $(elm).append(data.files[index].preview); |
---|
434 | }); |
---|
435 | }, |
---|
436 | |
---|
437 | _renderUpload: function (files) { |
---|
438 | return this._renderTemplate( |
---|
439 | this.options.uploadTemplate, |
---|
440 | files |
---|
441 | ); |
---|
442 | }, |
---|
443 | |
---|
444 | _renderDownload: function (files) { |
---|
445 | return this._renderTemplate( |
---|
446 | this.options.downloadTemplate, |
---|
447 | files |
---|
448 | ).find('a[download]').each(this._enableDragToDesktop).end(); |
---|
449 | }, |
---|
450 | |
---|
451 | _startHandler: function (e) { |
---|
452 | e.preventDefault(); |
---|
453 | var button = $(e.currentTarget), |
---|
454 | template = button.closest('.template-upload'), |
---|
455 | data = template.data('data'); |
---|
456 | if (data && data.submit && !data.jqXHR && data.submit()) { |
---|
457 | button.prop('disabled', true); |
---|
458 | } |
---|
459 | }, |
---|
460 | |
---|
461 | _cancelHandler: function (e) { |
---|
462 | e.preventDefault(); |
---|
463 | var template = $(e.currentTarget).closest('.template-upload'), |
---|
464 | data = template.data('data') || {}; |
---|
465 | if (!data.jqXHR) { |
---|
466 | data.errorThrown = 'abort'; |
---|
467 | this._trigger('fail', e, data); |
---|
468 | } else { |
---|
469 | data.jqXHR.abort(); |
---|
470 | } |
---|
471 | }, |
---|
472 | |
---|
473 | _deleteHandler: function (e) { |
---|
474 | e.preventDefault(); |
---|
475 | var button = $(e.currentTarget); |
---|
476 | this._trigger('destroy', e, $.extend({ |
---|
477 | context: button.closest('.template-download'), |
---|
478 | type: 'DELETE' |
---|
479 | }, button.data())); |
---|
480 | }, |
---|
481 | |
---|
482 | _forceReflow: function (node) { |
---|
483 | return $.support.transition && node.length && |
---|
484 | node[0].offsetWidth; |
---|
485 | }, |
---|
486 | |
---|
487 | _transition: function (node) { |
---|
488 | var dfd = $.Deferred(); |
---|
489 | if ($.support.transition && node.hasClass('fade') && node.is(':visible')) { |
---|
490 | node.bind( |
---|
491 | $.support.transition.end, |
---|
492 | function (e) { |
---|
493 | // Make sure we don't respond to other transitions events |
---|
494 | // in the container element, e.g. from button elements: |
---|
495 | if (e.target === node[0]) { |
---|
496 | node.unbind($.support.transition.end); |
---|
497 | dfd.resolveWith(node); |
---|
498 | } |
---|
499 | } |
---|
500 | ).toggleClass('in'); |
---|
501 | } else { |
---|
502 | node.toggleClass('in'); |
---|
503 | dfd.resolveWith(node); |
---|
504 | } |
---|
505 | return dfd; |
---|
506 | }, |
---|
507 | |
---|
508 | _initButtonBarEventHandlers: function () { |
---|
509 | var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), |
---|
510 | filesList = this.options.filesContainer; |
---|
511 | this._on(fileUploadButtonBar.find('.start'), { |
---|
512 | click: function (e) { |
---|
513 | e.preventDefault(); |
---|
514 | filesList.find('.start').click(); |
---|
515 | } |
---|
516 | }); |
---|
517 | this._on(fileUploadButtonBar.find('.cancel'), { |
---|
518 | click: function (e) { |
---|
519 | e.preventDefault(); |
---|
520 | filesList.find('.cancel').click(); |
---|
521 | } |
---|
522 | }); |
---|
523 | this._on(fileUploadButtonBar.find('.delete'), { |
---|
524 | click: function (e) { |
---|
525 | e.preventDefault(); |
---|
526 | filesList.find('.toggle:checked') |
---|
527 | .closest('.template-download') |
---|
528 | .find('.delete').click(); |
---|
529 | fileUploadButtonBar.find('.toggle') |
---|
530 | .prop('checked', false); |
---|
531 | } |
---|
532 | }); |
---|
533 | this._on(fileUploadButtonBar.find('.toggle'), { |
---|
534 | change: function (e) { |
---|
535 | filesList.find('.toggle').prop( |
---|
536 | 'checked', |
---|
537 | $(e.currentTarget).is(':checked') |
---|
538 | ); |
---|
539 | } |
---|
540 | }); |
---|
541 | }, |
---|
542 | |
---|
543 | _destroyButtonBarEventHandlers: function () { |
---|
544 | this._off( |
---|
545 | this.element.find('.fileupload-buttonbar') |
---|
546 | .find('.start, .cancel, .delete'), |
---|
547 | 'click' |
---|
548 | ); |
---|
549 | this._off( |
---|
550 | this.element.find('.fileupload-buttonbar .toggle'), |
---|
551 | 'change.' |
---|
552 | ); |
---|
553 | }, |
---|
554 | |
---|
555 | _initEventHandlers: function () { |
---|
556 | this._super(); |
---|
557 | this._on(this.options.filesContainer, { |
---|
558 | 'click .start': this._startHandler, |
---|
559 | 'click .cancel': this._cancelHandler, |
---|
560 | 'click .delete': this._deleteHandler |
---|
561 | }); |
---|
562 | this._initButtonBarEventHandlers(); |
---|
563 | }, |
---|
564 | |
---|
565 | _destroyEventHandlers: function () { |
---|
566 | this._destroyButtonBarEventHandlers(); |
---|
567 | this._off(this.options.filesContainer, 'click'); |
---|
568 | this._super(); |
---|
569 | }, |
---|
570 | |
---|
571 | _enableFileInputButton: function () { |
---|
572 | this.element.find('.fileinput-button input') |
---|
573 | .prop('disabled', false) |
---|
574 | .parent().removeClass('disabled'); |
---|
575 | }, |
---|
576 | |
---|
577 | _disableFileInputButton: function () { |
---|
578 | this.element.find('.fileinput-button input') |
---|
579 | .prop('disabled', true) |
---|
580 | .parent().addClass('disabled'); |
---|
581 | }, |
---|
582 | |
---|
583 | _initTemplates: function () { |
---|
584 | var options = this.options; |
---|
585 | options.templatesContainer = this.document[0].createElement( |
---|
586 | options.filesContainer.prop('nodeName') |
---|
587 | ); |
---|
588 | if (tmpl) { |
---|
589 | if (options.uploadTemplateId) { |
---|
590 | options.uploadTemplate = tmpl(options.uploadTemplateId); |
---|
591 | } |
---|
592 | if (options.downloadTemplateId) { |
---|
593 | options.downloadTemplate = tmpl(options.downloadTemplateId); |
---|
594 | } |
---|
595 | } |
---|
596 | }, |
---|
597 | |
---|
598 | _initFilesContainer: function () { |
---|
599 | var options = this.options; |
---|
600 | if (options.filesContainer === undefined) { |
---|
601 | options.filesContainer = this.element.find('.files'); |
---|
602 | } else if (!(options.filesContainer instanceof $)) { |
---|
603 | options.filesContainer = $(options.filesContainer); |
---|
604 | } |
---|
605 | }, |
---|
606 | |
---|
607 | _initSpecialOptions: function () { |
---|
608 | this._super(); |
---|
609 | this._initFilesContainer(); |
---|
610 | this._initTemplates(); |
---|
611 | }, |
---|
612 | |
---|
613 | _create: function () { |
---|
614 | this._super(); |
---|
615 | this._resetFinishedDeferreds(); |
---|
616 | if (!$.support.fileInput) { |
---|
617 | this._disableFileInputButton(); |
---|
618 | } |
---|
619 | }, |
---|
620 | |
---|
621 | enable: function () { |
---|
622 | var wasDisabled = false; |
---|
623 | if (this.options.disabled) { |
---|
624 | wasDisabled = true; |
---|
625 | } |
---|
626 | this._super(); |
---|
627 | if (wasDisabled) { |
---|
628 | this.element.find('input, button').prop('disabled', false); |
---|
629 | this._enableFileInputButton(); |
---|
630 | } |
---|
631 | }, |
---|
632 | |
---|
633 | disable: function () { |
---|
634 | if (!this.options.disabled) { |
---|
635 | this.element.find('input, button').prop('disabled', true); |
---|
636 | this._disableFileInputButton(); |
---|
637 | } |
---|
638 | this._super(); |
---|
639 | } |
---|
640 | |
---|
641 | }); |
---|
642 | |
---|
643 | })); |
---|