|
@@ -55,7 +55,7 @@
|
|
return obj.getMsgSelected(n);
|
|
return obj.getMsgSelected(n);
|
|
},
|
|
},
|
|
initId: obj.previewInitId,
|
|
initId: obj.previewInitId,
|
|
- footer: obj.getLayoutTemplate('footer'),
|
|
|
|
|
|
+ footer: obj.getLayoutTemplate('footer').replace(/\{progress\}/g, obj.renderThumbProgress()),
|
|
isDelete: obj.initialPreviewShowDelete,
|
|
isDelete: obj.initialPreviewShowDelete,
|
|
caption: obj.initialCaption,
|
|
caption: obj.initialCaption,
|
|
actions: function (showUpload, showDelete, disabled, url, key) {
|
|
actions: function (showUpload, showDelete, disabled, url, key) {
|
|
@@ -282,7 +282,7 @@
|
|
'</div>',
|
|
'</div>',
|
|
tFooter = '<div class="file-thumbnail-footer">\n' +
|
|
tFooter = '<div class="file-thumbnail-footer">\n' +
|
|
' <div class="file-footer-caption" title="{caption}">{caption}</div>\n' +
|
|
' <div class="file-footer-caption" title="{caption}">{caption}</div>\n' +
|
|
- ' {actions}\n' +
|
|
|
|
|
|
+ ' {progress} {actions}\n' +
|
|
'</div>',
|
|
'</div>',
|
|
tActions = '<div class="file-actions">\n' +
|
|
tActions = '<div class="file-actions">\n' +
|
|
' <div class="file-footer-buttons">\n' +
|
|
' <div class="file-footer-buttons">\n' +
|
|
@@ -510,10 +510,16 @@
|
|
self.reader = null;
|
|
self.reader = null;
|
|
self.formdata = {};
|
|
self.formdata = {};
|
|
self.filestack = [];
|
|
self.filestack = [];
|
|
|
|
+ self.uploadCount = 0;
|
|
|
|
+ self.uploadStatus = {};
|
|
|
|
+ self.fileprogress = [];
|
|
self.ajaxRequests = [];
|
|
self.ajaxRequests = [];
|
|
self.isError = false;
|
|
self.isError = false;
|
|
self.ajaxAborted = false;
|
|
self.ajaxAborted = false;
|
|
self.cancelling = false;
|
|
self.cancelling = false;
|
|
|
|
+ t = self.getLayoutTemplate('progress');
|
|
|
|
+ self.progressTemplate = t.replace('{class}', self.progressClass);
|
|
|
|
+ self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass);
|
|
self.dropZoneEnabled = hasDragDropSupport() && self.dropZoneEnabled;
|
|
self.dropZoneEnabled = hasDragDropSupport() && self.dropZoneEnabled;
|
|
self.isDisabled = self.$element.attr('disabled') || self.$element.attr('readonly');
|
|
self.isDisabled = self.$element.attr('disabled') || self.$element.attr('readonly');
|
|
self.isUploadable = hasFileUploadSupport() && !isEmpty(self.uploadUrl);
|
|
self.isUploadable = hasFileUploadSupport() && !isEmpty(self.uploadUrl);
|
|
@@ -550,12 +556,7 @@
|
|
self.initPreviewDeletes();
|
|
self.initPreviewDeletes();
|
|
self.options = options;
|
|
self.options = options;
|
|
self.setFileDropZoneTitle();
|
|
self.setFileDropZoneTitle();
|
|
- self.uploadCount = 0;
|
|
|
|
- self.uploadPercent = 0;
|
|
|
|
self.$element.removeClass('file-loading');
|
|
self.$element.removeClass('file-loading');
|
|
- t = self.getLayoutTemplate('progress');
|
|
|
|
- self.progressTemplate = t.replace('{class}', self.progressClass);
|
|
|
|
- self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass);
|
|
|
|
if (self.$element.attr('disabled')) {
|
|
if (self.$element.attr('disabled')) {
|
|
self.disable();
|
|
self.disable();
|
|
}
|
|
}
|
|
@@ -736,11 +737,12 @@
|
|
self.clearFileInput();
|
|
self.clearFileInput();
|
|
addCss(self.$container, 'has-error');
|
|
addCss(self.$container, 'has-error');
|
|
},
|
|
},
|
|
- setProgress: function (p) {
|
|
|
|
|
|
+ setProgress: function (p, $el) {
|
|
var self = this, pct = Math.min(p, 100),
|
|
var self = this, pct = Math.min(p, 100),
|
|
template = pct < 100 ? self.progressTemplate : self.progressCompleteTemplate;
|
|
template = pct < 100 ? self.progressTemplate : self.progressCompleteTemplate;
|
|
|
|
+ $el = $el || self.$progress;
|
|
if (!isEmpty(template)) {
|
|
if (!isEmpty(template)) {
|
|
- self.$progress.html(template.replace(/\{percent\}/g, pct));
|
|
|
|
|
|
+ $el.html(template.replace(/\{percent\}/g, pct));
|
|
}
|
|
}
|
|
},
|
|
},
|
|
upload: function () {
|
|
upload: function () {
|
|
@@ -756,9 +758,9 @@
|
|
self.resetUpload();
|
|
self.resetUpload();
|
|
self.$progress.removeClass('hide');
|
|
self.$progress.removeClass('hide');
|
|
self.uploadCount = 0;
|
|
self.uploadCount = 0;
|
|
- self.uploadPercent = 0;
|
|
|
|
|
|
+ self.uploadStatus = {};
|
|
self.lock();
|
|
self.lock();
|
|
- self.setProgress(0);
|
|
|
|
|
|
+ self.setProgress(2);
|
|
if (totLen === 0 && hasExtraData) {
|
|
if (totLen === 0 && hasExtraData) {
|
|
self.uploadExtraOnly();
|
|
self.uploadExtraOnly();
|
|
return;
|
|
return;
|
|
@@ -948,18 +950,23 @@
|
|
var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural;
|
|
var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural;
|
|
return self.msgSelected.replace('{n}', n).replace('{files}', strFiles);
|
|
return self.msgSelected.replace('{n}', n).replace('{files}', strFiles);
|
|
},
|
|
},
|
|
|
|
+ renderThumbProgress: function() {
|
|
|
|
+ return '<div class="file-thumb-progress hide">' + this.progressTemplate.replace(/\{percent\}/g, '0') + '</div>';
|
|
|
|
+ },
|
|
renderFileFooter: function (caption, width) {
|
|
renderFileFooter: function (caption, width) {
|
|
var self = this, config = self.fileActionSettings, footer, out,
|
|
var self = this, config = self.fileActionSettings, footer, out,
|
|
- template = self.getLayoutTemplate('footer');
|
|
|
|
|
|
+ template = self.getLayoutTemplate('footer'), progress = self.progressTemplate;
|
|
if (self.isUploadable) {
|
|
if (self.isUploadable) {
|
|
footer = template.replace(/\{actions\}/g, self.renderFileActions(true, true, false, false, false));
|
|
footer = template.replace(/\{actions\}/g, self.renderFileActions(true, true, false, false, false));
|
|
out = footer.replace(/\{caption\}/g, caption)
|
|
out = footer.replace(/\{caption\}/g, caption)
|
|
.replace(/\{width\}/g, width)
|
|
.replace(/\{width\}/g, width)
|
|
|
|
+ .replace(/\{progress\}/g, self.renderThumbProgress())
|
|
.replace(/\{indicator\}/g, config.indicatorNew)
|
|
.replace(/\{indicator\}/g, config.indicatorNew)
|
|
.replace(/\{indicatorTitle\}/g, config.indicatorNewTitle);
|
|
.replace(/\{indicatorTitle\}/g, config.indicatorNewTitle);
|
|
} else {
|
|
} else {
|
|
out = template.replace(/\{actions\}/g, '')
|
|
out = template.replace(/\{actions\}/g, '')
|
|
.replace(/\{caption\}/g, caption)
|
|
.replace(/\{caption\}/g, caption)
|
|
|
|
+ .replace(/\{progress\}/g, '')
|
|
.replace(/\{width\}/g, width)
|
|
.replace(/\{width\}/g, width)
|
|
.replace(/\{indicator\}/g, '')
|
|
.replace(/\{indicator\}/g, '')
|
|
.replace(/\{indicatorTitle\}/g, '');
|
|
.replace(/\{indicatorTitle\}/g, '');
|
|
@@ -1161,7 +1168,7 @@
|
|
var self = this;
|
|
var self = this;
|
|
self.uploadCache = {content: [], config: [], tags: [], append: true};
|
|
self.uploadCache = {content: [], config: [], tags: [], append: true};
|
|
self.uploadCount = 0;
|
|
self.uploadCount = 0;
|
|
- self.uploadPercent = 0;
|
|
|
|
|
|
+ self.uploadStatus = {};
|
|
self.$btnUpload.removeAttr('disabled');
|
|
self.$btnUpload.removeAttr('disabled');
|
|
self.setProgress(0);
|
|
self.setProgress(0);
|
|
addCss(self.$progress, 'hide');
|
|
addCss(self.$progress, 'hide');
|
|
@@ -1314,16 +1321,29 @@
|
|
self.formdata.append(key, value);
|
|
self.formdata.append(key, value);
|
|
});
|
|
});
|
|
},
|
|
},
|
|
- initXhr: function (xhrobj, factor) {
|
|
|
|
|
|
+ setAsyncUploadStatus: function(previewId, pct, total) {
|
|
|
|
+ var self = this, sum = 0, status = self.uploadStatus[previewId] || 0;
|
|
|
|
+ self.setProgress(pct, $('#' + previewId).find('.file-thumb-progress'));
|
|
|
|
+ self.uploadStatus[previewId] = pct;
|
|
|
|
+ $.each(self.uploadStatus, function (key, value) {
|
|
|
|
+ sum += value;
|
|
|
|
+ });
|
|
|
|
+ self.setProgress(Math.ceil(sum / total));
|
|
|
|
+
|
|
|
|
+ },
|
|
|
|
+ initXhr: function (xhrobj, previewId, fileCount) {
|
|
var self = this;
|
|
var self = this;
|
|
if (xhrobj.upload) {
|
|
if (xhrobj.upload) {
|
|
xhrobj.upload.addEventListener('progress', function (event) {
|
|
xhrobj.upload.addEventListener('progress', function (event) {
|
|
var pct = 0, position = event.loaded || event.position, total = event.total;
|
|
var pct = 0, position = event.loaded || event.position, total = event.total;
|
|
if (event.lengthComputable) {
|
|
if (event.lengthComputable) {
|
|
- pct = Math.ceil(position / total * factor);
|
|
|
|
|
|
+ pct = Math.ceil(position / total * 100);
|
|
|
|
+ }
|
|
|
|
+ if (previewId) {
|
|
|
|
+ self.setAsyncUploadStatus(previewId, pct, fileCount);
|
|
|
|
+ } else {
|
|
|
|
+ self.setProgress(Math.ceil(pct));
|
|
}
|
|
}
|
|
- self.uploadPercent = Math.max(pct, self.uploadPercent);
|
|
|
|
- self.setProgress(self.uploadPercent);
|
|
|
|
}, false);
|
|
}, false);
|
|
}
|
|
}
|
|
return xhrobj;
|
|
return xhrobj;
|
|
@@ -1335,7 +1355,7 @@
|
|
settings = $.extend({
|
|
settings = $.extend({
|
|
xhr: function () {
|
|
xhr: function () {
|
|
var xhrobj = $.ajaxSettings.xhr();
|
|
var xhrobj = $.ajaxSettings.xhr();
|
|
- return self.initXhr(xhrobj, 98);
|
|
|
|
|
|
+ return self.initXhr(xhrobj, previewId, self.getFileStack().length);
|
|
},
|
|
},
|
|
url: self.uploadUrl,
|
|
url: self.uploadUrl,
|
|
type: 'POST',
|
|
type: 'POST',
|
|
@@ -1411,9 +1431,10 @@
|
|
var self = this, total = self.getFileStack().length, formdata = new FormData(), outData,
|
|
var self = this, total = self.getFileStack().length, formdata = new FormData(), outData,
|
|
previewId = self.previewInitId + "-" + i, $thumb = $('#' + previewId + ':not(.file-preview-initial)'),
|
|
previewId = self.previewInitId + "-" + i, $thumb = $('#' + previewId + ':not(.file-preview-initial)'),
|
|
pct, chkComplete, $btnUpload = $thumb.find('.kv-file-upload'), $btnDelete = $thumb.find('.kv-file-remove'),
|
|
pct, chkComplete, $btnUpload = $thumb.find('.kv-file-upload'), $btnDelete = $thumb.find('.kv-file-remove'),
|
|
- updateProgress, hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData),
|
|
|
|
|
|
+ hasPostData = self.filestack.length > 0 || !$.isEmptyObject(self.uploadExtraData),
|
|
resetActions, fnBefore, fnSuccess, fnComplete, fnError, params = {id: previewId, index: i};
|
|
resetActions, fnBefore, fnSuccess, fnComplete, fnError, params = {id: previewId, index: i};
|
|
self.formdata = formdata;
|
|
self.formdata = formdata;
|
|
|
|
+ $('#' + previewId).find('.file-thumb-progress').removeClass('hide');
|
|
if (total === 0 || !hasPostData || $btnUpload.hasClass('disabled') || self.abort(params)) {
|
|
if (total === 0 || !hasPostData || $btnUpload.hasClass('disabled') || self.abort(params)) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -1430,22 +1451,14 @@
|
|
self.initPreview();
|
|
self.initPreview();
|
|
self.initPreviewDeletes();
|
|
self.initPreviewDeletes();
|
|
}
|
|
}
|
|
- self.setProgress(100);
|
|
|
|
self.unlock();
|
|
self.unlock();
|
|
self.clearFileInput();
|
|
self.clearFileInput();
|
|
self.raise('filebatchuploadcomplete', [self.filestack, self.getExtraData()]);
|
|
self.raise('filebatchuploadcomplete', [self.filestack, self.getExtraData()]);
|
|
|
|
+ self.uploadCount = 0;
|
|
|
|
+ self.uploadStatus = {};
|
|
|
|
+ self.setProgress(100);
|
|
}, 100);
|
|
}, 100);
|
|
};
|
|
};
|
|
- updateProgress = function () {
|
|
|
|
- if (!allFiles || total === 0 || self.uploadPercent >= 100) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- self.uploadCount += 1;
|
|
|
|
- pct = 80 + Math.ceil(self.uploadCount * 20 / total);
|
|
|
|
- self.uploadPercent = Math.max(pct, self.uploadPercent);
|
|
|
|
- self.setProgress(self.uploadPercent);
|
|
|
|
- self.initPreviewDeletes();
|
|
|
|
- };
|
|
|
|
resetActions = function () {
|
|
resetActions = function () {
|
|
$btnUpload.removeAttr('disabled');
|
|
$btnUpload.removeAttr('disabled');
|
|
$btnDelete.removeAttr('disabled');
|
|
$btnDelete.removeAttr('disabled');
|
|
@@ -1490,7 +1503,6 @@
|
|
};
|
|
};
|
|
fnComplete = function () {
|
|
fnComplete = function () {
|
|
setTimeout(function () {
|
|
setTimeout(function () {
|
|
- updateProgress();
|
|
|
|
resetActions();
|
|
resetActions();
|
|
if (!allFiles) {
|
|
if (!allFiles) {
|
|
self.unlock(false);
|
|
self.unlock(false);
|
|
@@ -1502,6 +1514,7 @@
|
|
};
|
|
};
|
|
fnError = function (jqXHR, textStatus, errorThrown) {
|
|
fnError = function (jqXHR, textStatus, errorThrown) {
|
|
var errMsg = self.parseError(jqXHR, errorThrown, (allFiles ? files[i].name : null));
|
|
var errMsg = self.parseError(jqXHR, errorThrown, (allFiles ? files[i].name : null));
|
|
|
|
+ self.uploadStatus[previewId] = 100;
|
|
self.setThumbStatus($thumb, 'Error');
|
|
self.setThumbStatus($thumb, 'Error');
|
|
params = $.extend(params, self.getOutData(jqXHR));
|
|
params = $.extend(params, self.getOutData(jqXHR));
|
|
self.showUploadError(errMsg, params);
|
|
self.showUploadError(errMsg, params);
|
|
@@ -2327,6 +2340,7 @@
|
|
msgValidationErrorClass: 'text-danger',
|
|
msgValidationErrorClass: 'text-danger',
|
|
msgValidationErrorIcon: '<i class="glyphicon glyphicon-exclamation-sign"></i> ',
|
|
msgValidationErrorIcon: '<i class="glyphicon glyphicon-exclamation-sign"></i> ',
|
|
msgErrorClass: 'file-error-message',
|
|
msgErrorClass: 'file-error-message',
|
|
|
|
+ progressThumbClass: "progress-bar progress-bar-success progress-bar-striped active",
|
|
progressClass: "progress-bar progress-bar-success progress-bar-striped active",
|
|
progressClass: "progress-bar progress-bar-success progress-bar-striped active",
|
|
progressCompleteClass: "progress-bar progress-bar-success",
|
|
progressCompleteClass: "progress-bar progress-bar-success",
|
|
previewFileType: 'image',
|
|
previewFileType: 'image',
|