[5341] | 1 | /* |
---|
[6107] | 2 | * jQuery File Upload User Interface Plugin 6.7 |
---|
[5341] | 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: |
---|
[6107] | 9 | * http://www.opensource.org/licenses/MIT |
---|
[5341] | 10 | */ |
---|
| 11 | |
---|
| 12 | /*jslint nomen: true, unparam: true, regexp: true */ |
---|
[6107] | 13 | /*global define, window, document, URL, webkitURL, FileReader */ |
---|
[5341] | 14 | |
---|
[6107] | 15 | (function (factory) { |
---|
[5341] | 16 | 'use strict'; |
---|
[6107] | 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 | |
---|
[5341] | 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: |
---|
[6107] | 52 | minFileSize: undefined, |
---|
[5341] | 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: |
---|
[6107] | 58 | previewSourceFileTypes: /^image\/(gif|jpeg|png)$/, |
---|
| 59 | // The maximum file size of images that are to be displayed as preview: |
---|
| 60 | previewSourceMaxFileSize: 5000000, // 5MB |
---|
[5341] | 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, |
---|
[6107] | 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, |
---|
[5341] | 79 | // The expected data type of the upload response, sets the dataType |
---|
| 80 | // option of the $.ajax upload requests: |
---|
| 81 | dataType: 'json', |
---|
[6107] | 82 | |
---|
[5341] | 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) { |
---|
[6107] | 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 | }); |
---|
[5341] | 110 | }, |
---|
| 111 | // Callback for the start of each file upload request: |
---|
| 112 | send: function (e, data) { |
---|
[6107] | 113 | var that = $(this).data('fileupload'); |
---|
[5341] | 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: |
---|
[6107] | 127 | data.context |
---|
| 128 | .find('.progress').addClass( |
---|
| 129 | !$.support.transition && 'progress-animated' |
---|
| 130 | ) |
---|
| 131 | .find('.bar').css( |
---|
| 132 | 'width', |
---|
| 133 | parseInt(100, 10) + '%' |
---|
| 134 | ); |
---|
[5341] | 135 | } |
---|
[6107] | 136 | return that._trigger('sent', e, data); |
---|
[5341] | 137 | }, |
---|
| 138 | // Callback for successful uploads: |
---|
| 139 | done: function (e, data) { |
---|
[6107] | 140 | var that = $(this).data('fileupload'), |
---|
| 141 | template, |
---|
| 142 | preview; |
---|
[5341] | 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 | } |
---|
[6107] | 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 | ); |
---|
[5341] | 165 | }); |
---|
| 166 | } else { |
---|
[6107] | 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 | ); |
---|
[5341] | 176 | } |
---|
| 177 | }, |
---|
| 178 | // Callback for failed (abort or error) uploads: |
---|
| 179 | fail: function (e, data) { |
---|
[6107] | 180 | var that = $(this).data('fileupload'), |
---|
| 181 | template; |
---|
[5341] | 182 | that._adjustMaxNumberOfFiles(data.files.length); |
---|
| 183 | if (data.context) { |
---|
| 184 | data.context.each(function (index) { |
---|
[6107] | 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 | } |
---|
[5341] | 211 | }); |
---|
| 212 | } else if (data.errorThrown !== 'abort') { |
---|
| 213 | that._adjustMaxNumberOfFiles(-data.files.length); |
---|
| 214 | data.context = that._renderUpload(data.files) |
---|
[6107] | 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); |
---|
[5341] | 226 | } |
---|
| 227 | }, |
---|
| 228 | // Callback for upload progress events: |
---|
| 229 | progress: function (e, data) { |
---|
| 230 | if (data.context) { |
---|
[6107] | 231 | data.context.find('.progress .bar').css( |
---|
| 232 | 'width', |
---|
| 233 | parseInt(data.loaded / data.total * 100, 10) + '%' |
---|
[5341] | 234 | ); |
---|
| 235 | } |
---|
| 236 | }, |
---|
| 237 | // Callback for global upload progress events: |
---|
| 238 | progressall: function (e, data) { |
---|
[6107] | 239 | $(this).find('.fileupload-buttonbar .progress .bar').css( |
---|
| 240 | 'width', |
---|
| 241 | parseInt(data.loaded / data.total * 100, 10) + '%' |
---|
[5341] | 242 | ); |
---|
| 243 | }, |
---|
| 244 | // Callback for uploads start, equivalent to the global ajaxStart event: |
---|
[6107] | 245 | start: function (e) { |
---|
| 246 | var that = $(this).data('fileupload'); |
---|
| 247 | that._transition($(this).find('.fileupload-buttonbar .progress')).done( |
---|
| 248 | function () { |
---|
| 249 | that._trigger('started', e); |
---|
| 250 | } |
---|
| 251 | ); |
---|
[5341] | 252 | }, |
---|
| 253 | // Callback for uploads stop, equivalent to the global ajaxStop event: |
---|
[6107] | 254 | stop: function (e) { |
---|
| 255 | var that = $(this).data('fileupload'); |
---|
| 256 | that._transition($(this).find('.fileupload-buttonbar .progress')).done( |
---|
| 257 | function () { |
---|
| 258 | $(this).find('.bar').css('width', '0%'); |
---|
| 259 | that._trigger('stopped', e); |
---|
| 260 | } |
---|
| 261 | ); |
---|
[5341] | 262 | }, |
---|
| 263 | // Callback for file deletion: |
---|
| 264 | destroy: function (e, data) { |
---|
| 265 | var that = $(this).data('fileupload'); |
---|
| 266 | if (data.url) { |
---|
[6107] | 267 | $.ajax(data); |
---|
[5341] | 268 | } |
---|
[6107] | 269 | that._adjustMaxNumberOfFiles(1); |
---|
| 270 | that._transition(data.context).done( |
---|
| 271 | function () { |
---|
| 272 | $(this).remove(); |
---|
| 273 | that._trigger('destroyed', e, data); |
---|
| 274 | } |
---|
[5341] | 275 | ); |
---|
| 276 | } |
---|
| 277 | }, |
---|
| 278 | |
---|
| 279 | // Link handler, that allows to download files |
---|
| 280 | // by drag & drop of the links to the desktop: |
---|
| 281 | _enableDragToDesktop: function () { |
---|
| 282 | var link = $(this), |
---|
| 283 | url = link.prop('href'), |
---|
[6107] | 284 | name = link.prop('download'), |
---|
[5341] | 285 | type = 'application/octet-stream'; |
---|
| 286 | link.bind('dragstart', function (e) { |
---|
| 287 | try { |
---|
| 288 | e.originalEvent.dataTransfer.setData( |
---|
| 289 | 'DownloadURL', |
---|
| 290 | [type, name, url].join(':') |
---|
| 291 | ); |
---|
| 292 | } catch (err) {} |
---|
| 293 | }); |
---|
| 294 | }, |
---|
| 295 | |
---|
| 296 | _adjustMaxNumberOfFiles: function (operand) { |
---|
| 297 | if (typeof this.options.maxNumberOfFiles === 'number') { |
---|
| 298 | this.options.maxNumberOfFiles += operand; |
---|
| 299 | if (this.options.maxNumberOfFiles < 1) { |
---|
| 300 | this._disableFileInputButton(); |
---|
| 301 | } else { |
---|
| 302 | this._enableFileInputButton(); |
---|
| 303 | } |
---|
| 304 | } |
---|
| 305 | }, |
---|
| 306 | |
---|
[6107] | 307 | _formatFileSize: function (bytes) { |
---|
| 308 | if (typeof bytes !== 'number') { |
---|
[5341] | 309 | return ''; |
---|
| 310 | } |
---|
[6107] | 311 | if (bytes >= 1000000000) { |
---|
| 312 | return (bytes / 1000000000).toFixed(2) + ' GB'; |
---|
[5341] | 313 | } |
---|
[6107] | 314 | if (bytes >= 1000000) { |
---|
| 315 | return (bytes / 1000000).toFixed(2) + ' MB'; |
---|
[5341] | 316 | } |
---|
[6107] | 317 | return (bytes / 1000).toFixed(2) + ' KB'; |
---|
[5341] | 318 | }, |
---|
| 319 | |
---|
| 320 | _hasError: function (file) { |
---|
| 321 | if (file.error) { |
---|
| 322 | return file.error; |
---|
| 323 | } |
---|
| 324 | // The number of added files is subtracted from |
---|
| 325 | // maxNumberOfFiles before validation, so we check if |
---|
| 326 | // maxNumberOfFiles is below 0 (instead of below 1): |
---|
| 327 | if (this.options.maxNumberOfFiles < 0) { |
---|
| 328 | return 'maxNumberOfFiles'; |
---|
| 329 | } |
---|
| 330 | // Files are accepted if either the file type or the file name |
---|
| 331 | // matches against the acceptFileTypes regular expression, as |
---|
| 332 | // only browsers with support for the File API report the type: |
---|
| 333 | if (!(this.options.acceptFileTypes.test(file.type) || |
---|
| 334 | this.options.acceptFileTypes.test(file.name))) { |
---|
| 335 | return 'acceptFileTypes'; |
---|
| 336 | } |
---|
| 337 | if (this.options.maxFileSize && |
---|
| 338 | file.size > this.options.maxFileSize) { |
---|
| 339 | return 'maxFileSize'; |
---|
| 340 | } |
---|
| 341 | if (typeof file.size === 'number' && |
---|
| 342 | file.size < this.options.minFileSize) { |
---|
| 343 | return 'minFileSize'; |
---|
| 344 | } |
---|
| 345 | return null; |
---|
| 346 | }, |
---|
| 347 | |
---|
| 348 | _validate: function (files) { |
---|
| 349 | var that = this, |
---|
| 350 | valid = !!files.length; |
---|
| 351 | $.each(files, function (index, file) { |
---|
| 352 | file.error = that._hasError(file); |
---|
| 353 | if (file.error) { |
---|
| 354 | valid = false; |
---|
| 355 | } |
---|
| 356 | }); |
---|
| 357 | return valid; |
---|
| 358 | }, |
---|
| 359 | |
---|
[6107] | 360 | _renderTemplate: function (func, files) { |
---|
| 361 | if (!func) { |
---|
| 362 | return $(); |
---|
| 363 | } |
---|
| 364 | var result = func({ |
---|
| 365 | files: files, |
---|
| 366 | formatFileSize: this._formatFileSize, |
---|
| 367 | options: this.options |
---|
| 368 | }); |
---|
| 369 | if (result instanceof $) { |
---|
| 370 | return result; |
---|
| 371 | } |
---|
| 372 | return $(this.options.templatesContainer).html(result).children(); |
---|
[5341] | 373 | }, |
---|
| 374 | |
---|
[6107] | 375 | _renderPreview: function (file, node) { |
---|
[5341] | 376 | var that = this, |
---|
| 377 | options = this.options, |
---|
[6107] | 378 | dfd = $.Deferred(); |
---|
| 379 | return ((loadImage && loadImage( |
---|
| 380 | file, |
---|
| 381 | function (img) { |
---|
| 382 | node.append(img); |
---|
| 383 | that._forceReflow(node); |
---|
| 384 | that._transition(node).done(function () { |
---|
| 385 | dfd.resolveWith(node); |
---|
| 386 | }); |
---|
| 387 | if (!$.contains(document.body, node[0])) { |
---|
| 388 | // If the element is not part of the DOM, |
---|
| 389 | // transition events are not triggered, |
---|
| 390 | // so we have to resolve manually: |
---|
| 391 | dfd.resolveWith(node); |
---|
[5341] | 392 | } |
---|
[6107] | 393 | }, |
---|
| 394 | { |
---|
| 395 | maxWidth: options.previewMaxWidth, |
---|
| 396 | maxHeight: options.previewMaxHeight, |
---|
| 397 | canvas: options.previewAsCanvas |
---|
| 398 | } |
---|
| 399 | )) || dfd.resolveWith(node)) && dfd; |
---|
[5341] | 400 | }, |
---|
| 401 | |
---|
[6107] | 402 | _renderPreviews: function (files, nodes) { |
---|
| 403 | var that = this, |
---|
| 404 | options = this.options; |
---|
| 405 | nodes.find('.preview span').each(function (index, element) { |
---|
| 406 | var file = files[index]; |
---|
| 407 | if (options.previewSourceFileTypes.test(file.type) && |
---|
| 408 | ($.type(options.previewSourceMaxFileSize) !== 'number' || |
---|
| 409 | file.size < options.previewSourceMaxFileSize)) { |
---|
| 410 | that._processingQueue = that._processingQueue.pipe(function () { |
---|
| 411 | var dfd = $.Deferred(); |
---|
| 412 | that._renderPreview(file, $(element)).done( |
---|
| 413 | function () { |
---|
| 414 | dfd.resolveWith(that); |
---|
| 415 | } |
---|
| 416 | ); |
---|
| 417 | return dfd.promise(); |
---|
| 418 | }); |
---|
| 419 | } |
---|
| 420 | }); |
---|
| 421 | return this._processingQueue; |
---|
[5341] | 422 | }, |
---|
| 423 | |
---|
[6107] | 424 | _renderUpload: function (files) { |
---|
| 425 | return this._renderTemplate( |
---|
| 426 | this.options.uploadTemplate, |
---|
| 427 | files |
---|
[5341] | 428 | ); |
---|
| 429 | }, |
---|
[6107] | 430 | |
---|
[5341] | 431 | _renderDownload: function (files) { |
---|
[6107] | 432 | return this._renderTemplate( |
---|
| 433 | this.options.downloadTemplate, |
---|
| 434 | files |
---|
| 435 | ).find('a[download]').each(this._enableDragToDesktop).end(); |
---|
[5341] | 436 | }, |
---|
[6107] | 437 | |
---|
[5341] | 438 | _startHandler: function (e) { |
---|
| 439 | e.preventDefault(); |
---|
[6107] | 440 | var button = $(this), |
---|
| 441 | template = button.closest('.template-upload'), |
---|
| 442 | data = template.data('data'); |
---|
| 443 | if (data && data.submit && !data.jqXHR && data.submit()) { |
---|
| 444 | button.prop('disabled', true); |
---|
[5341] | 445 | } |
---|
| 446 | }, |
---|
[6107] | 447 | |
---|
[5341] | 448 | _cancelHandler: function (e) { |
---|
| 449 | e.preventDefault(); |
---|
[6107] | 450 | var template = $(this).closest('.template-upload'), |
---|
| 451 | data = template.data('data') || {}; |
---|
[5341] | 452 | if (!data.jqXHR) { |
---|
| 453 | data.errorThrown = 'abort'; |
---|
| 454 | e.data.fileupload._trigger('fail', e, data); |
---|
| 455 | } else { |
---|
| 456 | data.jqXHR.abort(); |
---|
| 457 | } |
---|
| 458 | }, |
---|
[6107] | 459 | |
---|
[5341] | 460 | _deleteHandler: function (e) { |
---|
| 461 | e.preventDefault(); |
---|
| 462 | var button = $(this); |
---|
| 463 | e.data.fileupload._trigger('destroy', e, { |
---|
| 464 | context: button.closest('.template-download'), |
---|
| 465 | url: button.attr('data-url'), |
---|
[6107] | 466 | type: button.attr('data-type') || 'DELETE', |
---|
[5341] | 467 | dataType: e.data.fileupload.options.dataType |
---|
| 468 | }); |
---|
| 469 | }, |
---|
[6107] | 470 | |
---|
| 471 | _forceReflow: function (node) { |
---|
| 472 | this._reflow = $.support.transition && |
---|
| 473 | node.length && node[0].offsetWidth; |
---|
[5341] | 474 | }, |
---|
[6107] | 475 | |
---|
| 476 | _transition: function (node) { |
---|
| 477 | var that = this, |
---|
| 478 | dfd = $.Deferred(); |
---|
| 479 | if ($.support.transition && node.hasClass('fade')) { |
---|
| 480 | node.bind( |
---|
| 481 | $.support.transition.end, |
---|
| 482 | function (e) { |
---|
| 483 | // Make sure we don't respond to other transitions events |
---|
| 484 | // in the container element, e.g. from button elements: |
---|
| 485 | if (e.target === node[0]) { |
---|
| 486 | node.unbind($.support.transition.end); |
---|
| 487 | dfd.resolveWith(node); |
---|
| 488 | } |
---|
| 489 | } |
---|
| 490 | ).toggleClass('in'); |
---|
| 491 | } else { |
---|
| 492 | node.toggleClass('in'); |
---|
| 493 | dfd.resolveWith(node); |
---|
| 494 | } |
---|
| 495 | return dfd; |
---|
[5341] | 496 | }, |
---|
| 497 | |
---|
[6107] | 498 | _initButtonBarEventHandlers: function () { |
---|
[5341] | 499 | var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), |
---|
[6107] | 500 | filesList = this.options.filesContainer, |
---|
[5341] | 501 | ns = this.options.namespace; |
---|
| 502 | fileUploadButtonBar.find('.start') |
---|
| 503 | .bind('click.' + ns, function (e) { |
---|
| 504 | e.preventDefault(); |
---|
| 505 | filesList.find('.start button').click(); |
---|
| 506 | }); |
---|
| 507 | fileUploadButtonBar.find('.cancel') |
---|
| 508 | .bind('click.' + ns, function (e) { |
---|
| 509 | e.preventDefault(); |
---|
| 510 | filesList.find('.cancel button').click(); |
---|
| 511 | }); |
---|
| 512 | fileUploadButtonBar.find('.delete') |
---|
| 513 | .bind('click.' + ns, function (e) { |
---|
| 514 | e.preventDefault(); |
---|
[6107] | 515 | filesList.find('.delete input:checked') |
---|
| 516 | .siblings('button').click(); |
---|
| 517 | fileUploadButtonBar.find('.toggle') |
---|
| 518 | .prop('checked', false); |
---|
[5341] | 519 | }); |
---|
[6107] | 520 | fileUploadButtonBar.find('.toggle') |
---|
| 521 | .bind('change.' + ns, function (e) { |
---|
| 522 | filesList.find('.delete input').prop( |
---|
| 523 | 'checked', |
---|
| 524 | $(this).is(':checked') |
---|
| 525 | ); |
---|
| 526 | }); |
---|
[5341] | 527 | }, |
---|
[6107] | 528 | |
---|
| 529 | _destroyButtonBarEventHandlers: function () { |
---|
[5341] | 530 | this.element.find('.fileupload-buttonbar button') |
---|
[6107] | 531 | .unbind('click.' + this.options.namespace); |
---|
| 532 | this.element.find('.fileupload-buttonbar .toggle') |
---|
| 533 | .unbind('change.' + this.options.namespace); |
---|
[5341] | 534 | }, |
---|
| 535 | |
---|
[6107] | 536 | _initEventHandlers: function () { |
---|
| 537 | parentWidget.prototype._initEventHandlers.call(this); |
---|
| 538 | var eventData = {fileupload: this}; |
---|
| 539 | this.options.filesContainer |
---|
| 540 | .delegate( |
---|
| 541 | '.start button', |
---|
| 542 | 'click.' + this.options.namespace, |
---|
| 543 | eventData, |
---|
| 544 | this._startHandler |
---|
| 545 | ) |
---|
| 546 | .delegate( |
---|
| 547 | '.cancel button', |
---|
| 548 | 'click.' + this.options.namespace, |
---|
| 549 | eventData, |
---|
| 550 | this._cancelHandler |
---|
| 551 | ) |
---|
| 552 | .delegate( |
---|
| 553 | '.delete button', |
---|
| 554 | 'click.' + this.options.namespace, |
---|
| 555 | eventData, |
---|
| 556 | this._deleteHandler |
---|
| 557 | ); |
---|
| 558 | this._initButtonBarEventHandlers(); |
---|
| 559 | }, |
---|
| 560 | |
---|
| 561 | _destroyEventHandlers: function () { |
---|
| 562 | var options = this.options; |
---|
| 563 | this._destroyButtonBarEventHandlers(); |
---|
| 564 | options.filesContainer |
---|
| 565 | .undelegate('.start button', 'click.' + options.namespace) |
---|
| 566 | .undelegate('.cancel button', 'click.' + options.namespace) |
---|
| 567 | .undelegate('.delete button', 'click.' + options.namespace); |
---|
| 568 | parentWidget.prototype._destroyEventHandlers.call(this); |
---|
| 569 | }, |
---|
| 570 | |
---|
[5341] | 571 | _enableFileInputButton: function () { |
---|
[6107] | 572 | this.element.find('.fileinput-button input') |
---|
| 573 | .prop('disabled', false) |
---|
| 574 | .parent().removeClass('disabled'); |
---|
[5341] | 575 | }, |
---|
| 576 | |
---|
| 577 | _disableFileInputButton: function () { |
---|
[6107] | 578 | this.element.find('.fileinput-button input') |
---|
| 579 | .prop('disabled', true) |
---|
| 580 | .parent().addClass('disabled'); |
---|
[5341] | 581 | }, |
---|
| 582 | |
---|
| 583 | _initTemplates: function () { |
---|
[6107] | 584 | var options = this.options; |
---|
| 585 | options.templatesContainer = document.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 | } |
---|
[5341] | 595 | } |
---|
[6107] | 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); |
---|
[5341] | 604 | } |
---|
| 605 | }, |
---|
| 606 | |
---|
[6107] | 607 | _initSpecialOptions: function () { |
---|
| 608 | parentWidget.prototype._initSpecialOptions.call(this); |
---|
| 609 | this._initFilesContainer(); |
---|
[5341] | 610 | this._initTemplates(); |
---|
| 611 | }, |
---|
[6107] | 612 | |
---|
| 613 | _create: function () { |
---|
| 614 | parentWidget.prototype._create.call(this); |
---|
| 615 | this._refreshOptionsList.push( |
---|
| 616 | 'filesContainer', |
---|
| 617 | 'uploadTemplateId', |
---|
| 618 | 'downloadTemplateId' |
---|
| 619 | ); |
---|
| 620 | if (!$.blueimpFP) { |
---|
| 621 | this._processingQueue = $.Deferred().resolveWith(this).promise(); |
---|
| 622 | this.process = function () { |
---|
| 623 | return this._processingQueue; |
---|
| 624 | }; |
---|
| 625 | } |
---|
[5341] | 626 | }, |
---|
[6107] | 627 | |
---|
[5341] | 628 | enable: function () { |
---|
[6107] | 629 | parentWidget.prototype.enable.call(this); |
---|
| 630 | this.element.find('input, button').prop('disabled', false); |
---|
[5341] | 631 | this._enableFileInputButton(); |
---|
| 632 | }, |
---|
[6107] | 633 | |
---|
[5341] | 634 | disable: function () { |
---|
[6107] | 635 | this.element.find('input, button').prop('disabled', true); |
---|
[5341] | 636 | this._disableFileInputButton(); |
---|
[6107] | 637 | parentWidget.prototype.disable.call(this); |
---|
[5341] | 638 | } |
---|
| 639 | |
---|
| 640 | }); |
---|
| 641 | |
---|
[6107] | 642 | })); |
---|