/**
* Create an uploader.
*
* The `.presentationUiUploader()` method make an element editable on click the element.
*
* Only applicable to <input type="file"> nodes.
*
* ### Examples
* Loads the Uploader to an input field to upload images.l,
*
* JavaScript:
*
*
* <input type="file" name="NewFile" class="ep-js" data-js="de_epages.presentationUiUploader({
* multiple:false,
* accept:'image/*',
* big:true,
* data:{
* ChangeAction:'SaveImage',
* ObjectID:#ObjectID,
* SCALE_WIDTH_l:#Shop.ProductImageLargeWidth,
* SCALE_HEIGHT_l:#Shop.ProductImageLargeHeight,
* SCALE_WIDTH_m:200,
* SCALE_WIDTH_s:100,
* SCALE_HEIGHT_s:100,
* SCALE_WIDTH_h:150,
* SCALE_HEIGHT_h:150,
* SCALE_WIDTH_xs:50,
* SCALE_HEIGHT_xs:33,
* SCALE_NAME_m:'ImageMedium',
* SCALE_NAME_s:'ImageSmall',
* SCALE_NAME_h:'ImageHotDeal'
* },
* callback:'?ViewAction='+ep.config.viewAction+'&ObjectID='+ep.config.objectId+'&DialogArea=ViewArea'
* })"/>
*
*
* @class jQuery.ui.presentationUiUploader
* @extends jQuery.widget
*
* @uses jQuery.dict
* @uses jQuery.tmpl
* @uses jQuery.i18n
* @uses jQuery.expr
* @uses jQuery.fn.form
* @uses jQuery.ui.widget
* @uses jQuery.ui.progressbar
* @uses de_epages
* @uses ep.ajaxTransport
* @uses ep.ui.dialog
* @since 6.12.0
*/
/**
* @cfg {String} [accept] A string of MIME types and/or MIME type groups.
*/
/**
* @cfg {String} [url] A string containing the URL to which the request is sent.
*/
/**
* @cfg {String} [buttonText] A string for the upload button
*/
/**
* @cfg {Object} [data] A map of additional data to send with the request.
*/
/**
* @cfg {Function,String} [callback] A url to open or method to call when upload process is finished. The callback method receives data and statusText as arguments.
*/
/**
* @cfg {Boolean} [multiple] A boolean indication whether to allow muplitple files to upload.
*/
/**
* @cfg {Boolean} [big] A boolean boolean short handle set style big.
*/
/**
* @cfg {String} [style] One of the available styles: normal,big,icon.
*/
/**
* @cfg {Array} [exists] An array including already existing files.
*/
/**
* See `jQuery.ui.presentationUiUploader` for details.
*
* @param {Object} [options] A map of additional options pass to the method.
* @param {String} [accept] A string of MIME types and/or MIME type groups.
* @param {String} [url] A string containing the URL to which the request is sent.
* @param {String} [buttonText] A string for the upload button
* @param {Object} [data] A map of additional data to send with the request.
* @param {Function,String} [callback] A url to open or method to call when upload process is finished. The callback method receives data and statusText as arguments.
* @param {Boolean} [multiple] A boolean indication whether to allow muplitple files to upload.
* @param {Boolean} [big] A boolean boolean short handle set style big.
* @param {String} [style] One of the available styles: normal,big,icon.
* @param {Array} [exists] An array including already existing files.
*
* @method presentationUiUploader
* @member jQuery
*
* @since 6.12.0
*/
/*
* @copyright © Copyright 2006-2010, epages GmbH, All Rights Reserved.
*
* @module de_epages.presentation.ui.uploader
*/
define("de_epages/presentation/ui/uploader", [
"jquery",
"ep",
"de_epages",
"util/mime",
"util/string",
"$dict!../dictionary",
"$tmpl!./uploader-progress",
"$tmpl!./uploader-error",
"$tmpl!./uploader-replace",
"jquery/i18n",
"jquery/expr",
"jquery/cookie",
"jquery/fn/form",
"jquery/ui/widget",
"jquery/ui/progressbar",
"ep/ajax",
"ep/ui/input",
"ep/ui/form",
"ep/ui/dialog",
"de_epages/presentation/ajaxtransport"
], function ($, ep, de_epages, mime, str, presentationDict, tmplUploaderProgress, tmplUploaderError, tmplUploaderReplace) {
/*
* @dictionary ep.dict
*
* @translation {Cancel}
* {Ignore}
* {Replace}
*
* @dictionary de_epages.presentation.dictionary
*
* @translation {FileUploadSingle}
* {FileUploadMultiple}
* {UploaderError}
* {UploaderReplace}
* {FixErrors}
* {FilesUploaded}
* {FileSizeLimitError}
* {InternalServerError}
* {FontLicenseRestricted}
* {MimetypeNotAcceptError}
* {UnknownError}
* {FeatureLimitExceeded}
* {InvalidMP3File}
* {InvalidImageFile}
* {ImageExceedsMegapixels}
* {VirusFoundError}
* {FileAlreadyExistsOnServer}
* {InvalidImageSize}
*/
var undef,
tCancel = presentationDict.translate('Cancel'),
tIgnore = presentationDict.translate('Ignore'),
tReplace = presentationDict.translate('ReplaceFiles'),
tUploadFile = presentationDict.translate('FileUploadSingle'),
tUploadFiles = presentationDict.translate('FileUploadMultiple'),
tUploaderError = presentationDict.translate('UploaderError'),
tUploaderReplace = presentationDict.translate('FileUploadMultiple'),
tFixErrors = presentationDict.translate('FixErrors'),
tFilesUploaded = presentationDict.translate('FilesUploaded'),
tAlreadyExists = presentationDict.translate('FileAlreadyExistsOnServer'),
tmplHelper = function () {
return {
i: 0,
even: function () {
return (this.i++) % 2 === 0;
},
shrink: function (string) {
return str.shrink(string, {
ratio: 0.5,
length: 40
});
},
translate: function (string) {
var before = string.replace(/ /g, ''),
after = presentationDict.translate(before);
return after !== before ? after : presentationDict.translate('UnknownError');
}
};
};
$.widget("ui.presentationUiUploader", {
options: {
// multiple: false,
// accept: '*/*',
exists: [],
style: 'normal',
big: false,
callback: $.noop,
url: '?',
tokenName: 'SecToken',
data: {
'ViewAction': 'JSONViewResponse'
}
},
_create: function () {
var self = this,
o = self.options;
self.elem = self.element
.attr("size", "1")
.addClass('de_epages-presentationUiUploader-button');
// create custom ui
self.custom = $('<span/>')
.addClass('ep-uiInput-custom ep-uiInput ep-uiInput-button')
.insertAfter(self.elem);
// bind upload handle
self.elem
.on('change.presentationUiUploader', $.proxy(self, '_upload'));
// stack of item data
self.dataStack = [];
// init options
self._setOptions({
'accept': mime.mime(o.accept || self.elem.attr('accept') || '*/*'),
'multiple': o.multiple || self.elem.attr('multiple') || false,
'style': o.big ? 'big' : o.style,
'disabled': !!o.disabled
});
},
_setOption: function (name, value) {
var o = this.options;
if (value !== undef) {
switch (name) {
case 'accept':
this.elem.attr(name, mime.mime(value));
break;
case 'multiple':
this.elem.attr(name, value);
this._setOption('style', o.style);
break;
case 'big':
this._setOption('style', 'big');
break;
case 'style':
switch (value) {
case 'big':
this.custom
.html('<span class="ep-sprite ep-sprite-s ico_s_fileupload"></span>' + (o.buttonText || (o.multiple ? tUploadFiles : tUploadFile)))
.addClass('ep-uiInput-big');
break;
case 'icon':
this.custom
.html('<span class="ep-sprite ep-sprite-s ico_s_fileupload ep-uiInput-buttonSpriteOnly"></span>')
.removeClass('ep-uiInput-big');
break;
case 'big-icon':
this.custom
.html('<span class="ep-sprite ep-sprite-m ico_m_fileupload ep-uiInput-buttonSpriteOnly"></span>')
.addClass('ep-uiInput-big');
break;
break;
case 'fontAwesome':
this.custom
.html('<i class="fa fa-upload"></i>' + (o.buttonText || (o.multiple ? tUploadFiles : tUploadFile)))
.addClass('ep-uiInput-big');
break;
default:
this.custom
.html('<span class="ep-sprite ep-sprite-s ico_s_fileupload"></span>' + (o.buttonText || (o.multiple ? tUploadFiles : tUploadFile)))
.removeClass('ep-uiInput-big');
break;
}
break;
}
}
return this._superApply(arguments);
},
// handle addClass to the wrap
addClass: function (name) {
this.elem.addClass(name);
},
// handle removeClass to the wrap
removeClass: function (name) {
this.elem.removeClass(name);
},
_upload: function (event, doReplace) {
var self = this,
o = self.options,
files = self.elem[0].files,
filesCheck = [],
filesExists = [],
cookies = $.cookie();
self.statusText = '';
self._errorClose({
close: $.noop
});
for (var i = 0, iLength = self.dataStack.length; i < iLength; i++) {
if (self.dataStack[i].ERROR) {
self.dataStack.splice(i, 1);
iLength--;
i--;
}
}
// ask for replace exixting files
if (!doReplace && o.exists.length) {
if (!files) {
files = [{
name: self.elem.val()
}];
}
filesCheck = $.map(files, function (file, i) {
return file.name || file.fileName;
});
ep.ajax({
async: false,
dataType: 'json',
data: {
ViewAction: "JSONUnicodeConverter",
ObjectID: ep.config.siteId,
Type: "File",
Strings: filesCheck
}
})
.done(function (data) {
filesCheck = data.Strings;
});
filesExists = $.map(filesCheck, function (name, i) {
return $.inArray(name, o.exists) >= 0 ? name : null;
});
if (filesExists.length) {
self._uploadReplace(filesExists);
return;
}
}
self._progressOpen({
close: function (event) {
self._uploadCancel();
}
});
// provide a flag for the server
o.data.ReplaceExistingFiles = doReplace ? 1 : 0;
// check if security token exists and add hidden input with security cookie information
if (cookies[o.tokenName]) {
o.data[o.tokenName] = cookies[o.tokenName];
}
self.uploadXHR = $.ajax({
url: o.url,
data: o.data,
dataType: 'json',
file: self.elem[0],
fileMimeAccept: o.accept
})
.progress($.proxy(self, '_uploadProgress'))
.done($.proxy(self, '_uploadSuccess'))
.fail($.proxy(self, '_uploadError'));
},
_uploadReplace: function (filesReplace) {
this._replaceCreate();
this.replace
.element
.html(tmplUploaderReplace([{
items: filesReplace,
tAlreadyExists: tAlreadyExists
}], tmplHelper()));
this._replaceOpen();
},
_uploadCancel: function () {
this.uploadXHR.abort();
this._errorClose();
},
_uploadProgress: function (event, statusText, jqXHR) {
var valueItem = event.loaded * 100 / event.total,
valueAll = event.itemLoaded * 100 / event.itemTotal;
this.progressbarItem.progressbar('value', valueItem);
this.progresstextItem.text(str.shrink(event.data.item.fileName, {
ratio: 0.5,
length: 65
}));
this.progressbarAll.progressbar('value', valueAll);
this.progresstextAll.text(tFilesUploaded + ': ' + event.itemLoaded + ' / ' + event.itemTotal);
if (/(success|error)/.test(statusText)) {
this.dataStack.push(event.data);
}
},
_uploadSuccess: function (data, statusText, jqXHR) {
this.statusText = statusText;
this._progressClose({
close: $.noop
});
this._uploadComplete();
},
//#JSCOVERAGE_IF 0
_uploadError: function (jqXHR, statusText, errorThrown) {
var self = this;
self.statusText = statusText;
self._errorCreate();
self.error
.element
.html(tmplUploaderError([{
items: self.dataStack
}], tmplHelper()));
self._progressClose({
close: $.noop
});
self._errorOpen({
close: function () {
self._uploadComplete();
}
});
},
//#JSCOVERAGE_ENDIF
_uploadComplete: function () {
var o = this.options,
dataStack = this.dataStack,
statusText = this.statusText,
formNode = $(this.elem[0].form);
this.elem.formReset();
this.dataStack = [];
this.statusText = '';
if ($.type(o.callback) == 'string') {
if (formNode.length) {
formNode.uiForm('option', 'showSaveWarn', false);
}
location.href = o.callback;
} else {
o.callback(dataStack, statusText);
if (formNode.length) {
formNode.trigger('change');
}
}
},
_progressOpen: function (options) {
if (!this.progress) {
this._progressCreate();
}
if (options) {
this.progress.option(options);
}
this.progress.open();
},
_progressClose: function (options) {
if (this.progress) {
if (options) {
this.progress.option(options);
}
this.progress.close();
}
},
_progressCreate: function () {
if (!this.progress) {
var self = this;
this.progress = $('<div class="de_epages-presentationUiUploader">')
.html(tmplUploaderProgress({}))
.uiDialog({
width: 350,
modal: true,
autoOpen: false,
title: self.options.multiple ? tUploadFiles : tUploadFile,
buttons: {
cancel: {
text: tCancel,
click: function () {
self._progressClose();
}
}
}
})
.find('.de_epages-presentationUiUploader-progressBar')
.progressbar()
.each(function (i) {
var elem = $(this);
self[i ? 'progressbarAll' : 'progressbarItem'] = elem;
self[i ? 'progresstextAll' : 'progresstextItem'] = elem.next();
})
.end()
.uiDialog('Instance');
}
},
_errorOpen: function (options) {
if (!this.error) {
this._errorCreate();
}
if (options) {
this.error.option(options);
}
this.error.open();
},
_errorClose: function (options) {
if (this.error) {
if (options) {
this.error.option(options);
}
this.error.close();
}
},
_errorCreate: function () {
if (!this.error) {
var self = this;
this.error = $('<div class="de_epages-presentationUiUploader">')
.html(tmplUploaderError({}))
.uiDialog({
width: 350,
modal: true,
autoOpen: false,
title: tUploaderError,
buttons: {
fixit: {
text: tFixErrors,
'class': 'epWidth-160',
click: function () {
self._errorClose({
close: $.noop
});
self.custom.trigger('click');
}
},
ignore: {
text: tCancel,
click: function () {
self._errorClose();
}
}
}
})
.uiDialog('Instance');
}
},
_replaceOpen: function (options) {
if (!this.replace) {
this._replaceCreate();
}
if (options) {
this.replace.option(options);
}
this.replace.open();
},
_replaceClose: function (options) {
if (this.replace) {
if (options) {
this.replace.option(options);
}
this.replace.close();
}
},
_replaceCreate: function () {
if (!this.replace) {
var self = this;
this.replace = $('<div class="de_epages-presentationUiUploader">')
.html(tmplUploaderError({}))
.uiDialog({
width: 350,
modal: true,
autoOpen: false,
title: tUploaderReplace,
buttons: {
replace: {
text: tReplace,
click: function () {
self._replaceClose();
self._upload({}, true);
}
},
cancel: {
text: tCancel,
click: function () {
self._replaceClose();
self.statusText = "abort";
self._uploadComplete();
}
}
}
})
.uiDialog('Instance');
}
},
/**
* This method removes the container on which the Uploader has been appended to.
*
* @method destroy
* @member jQuery.ui.presentationUiUploader
*
* @since 6.12.0
*/
destroy: function () {
var self = this;
if (self.error) {
self.error.destroy();
}
if (self.progress) {
self.progress.destroy();
}
self.custom
.remove();
self.elem
.off('.presentationUiUploader');
self._superApply(arguments);
}
});
return de_epages;
});