diff --git a/api/js/etemplate/et2_widget_file.js b/api/js/etemplate/et2_widget_file.js index 88dbbf3022..3d24d78af4 100644 --- a/api/js/etemplate/et2_widget_file.js +++ b/api/js/etemplate/et2_widget_file.js @@ -57,8 +57,8 @@ var et2_file = /** @class */ (function (_super) { _this.span = null; // Contains all submit buttons need to be disabled during upload process _this.disabled_buttons = jQuery("input[type='submit'], button"); - if (!_this.options.value) - _this.options.value = {}; + // Make sure it's an object, not an array, or values get lost when sent to server + _this.options.value = jQuery.extend({}, _this.options.value); if (!_this.options.id) { console.warn("File widget needs an ID. Used 'file_widget'."); _this.options.id = "file_widget"; @@ -75,26 +75,7 @@ var et2_file = /** @class */ (function (_super) { // Set up the URL to have the request ID & the widget ID var instance = _this.getInstanceManager(); var self = _this; - _this.asyncOptions = jQuery.extend({ - // Callbacks - onStart: function (event, file_count) { - return self.onStart(event, file_count); - }, - onFinish: function (event, file_count) { - self.onFinish.apply(self, [event, file_count]); - }, - onStartOne: function (event, file_name, index, file_count) { - }, - onFinishOne: function (event, response, name, number, total) { return self.finishUpload(event, response, name, number, total); }, - onProgress: function (event, progress, name, number, total) { return self.onProgress(event, progress, name, number, total); }, - onError: function (event, name, error) { return self.onError(event, name, error); }, - beforeSend: function (form) { return self.beforeSend(form); }, - chunkSize: _this.options.chunk_size || 1024 * 1024, - target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\File::ajax_upload"), - query: function (file) { return self.beforeSend(file); }, - // Disable checking for already uploaded chunks - testChunks: false - }, _this.asyncOptions); + _this.asyncOptions = jQuery.extend({}, _this.getAsyncOptions(_this)); _this.asyncOptions.fieldName = _this.options.id; _this.createInputWidget(); _this.set_readonly(_this.options.readonly); @@ -166,6 +147,31 @@ var et2_file = /** @class */ (function (_super) { } this.setDOMNode(this.node[0]); }; + /** + * Get any specific async upload options + */ + et2_file.prototype.getAsyncOptions = function (self) { + return { + // Callbacks + onStart: function (event, file_count) { + return self.onStart(event, file_count); + }, + onFinish: function (event, file_count) { + self.onFinish.apply(self, [event, file_count]); + }, + onStartOne: function (event, file_name, index, file_count) { + }, + onFinishOne: function (event, response, name, number, total) { return self.finishUpload(event, response, name, number, total); }, + onProgress: function (event, progress, name, number, total) { return self.onProgress(event, progress, name, number, total); }, + onError: function (event, name, error) { return self.onError(event, name, error); }, + beforeSend: function (form) { return self.beforeSend(form); }, + chunkSize: this.options.chunk_size || 1024 * 1024, + target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\File::ajax_upload"), + query: function (file) { return self.beforeSend(file); }, + // Disable checking for already uploaded chunks + testChunks: false + }; + }; /** * Set a widget or DOM node as a HTML5 file drop target * diff --git a/api/js/etemplate/et2_widget_file.ts b/api/js/etemplate/et2_widget_file.ts index e0fe1460b6..5abc7bbe47 100644 --- a/api/js/etemplate/et2_widget_file.ts +++ b/api/js/etemplate/et2_widget_file.ts @@ -130,7 +130,9 @@ export class et2_file extends et2_inputWidget this.span = null; // Contains all submit buttons need to be disabled during upload process this.disabled_buttons = jQuery("input[type='submit'], button"); - if(!this.options.value) this.options.value = {}; + + // Make sure it's an object, not an array, or values get lost when sent to server + this.options.value = jQuery.extend({},this.options.value); if(!this.options.id) { console.warn("File widget needs an ID. Used 'file_widget'."); @@ -155,28 +157,8 @@ export class et2_file extends et2_inputWidget let self = this; this.asyncOptions = jQuery.extend({ - // Callbacks - onStart: function(event, file_count) { - return self.onStart(event, file_count); - }, - onFinish: function(event, file_count) { - self.onFinish.apply(self, [event, file_count]) - }, - onStartOne: function(event, file_name, index, file_count) { - }, - onFinishOne: function(event, response, name, number, total) { return self.finishUpload(event,response,name,number,total);}, - onProgress: function(event, progress, name, number, total) { return self.onProgress(event,progress,name,number,total);}, - onError: function(event, name, error) { return self.onError(event,name,error);}, - beforeSend: function(form) { return self.beforeSend(form);}, - - chunkSize: this.options.chunk_size || 1024*1024, - - target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\File::ajax_upload"), - query: function(file) {return self.beforeSend(file);}, - // Disable checking for already uploaded chunks - testChunks: false - },this.asyncOptions); + },this.getAsyncOptions(this)); this.asyncOptions.fieldName = this.options.id; this.createInputWidget(); this.set_readonly(this.options.readonly); @@ -257,6 +239,35 @@ export class et2_file extends et2_inputWidget this.setDOMNode(this.node[0]); } + /** + * Get any specific async upload options + */ + getAsyncOptions(self: et2_file) + { + return { + // Callbacks + onStart: function(event, file_count) { + return self.onStart(event, file_count); + }, + onFinish: function(event, file_count) { + self.onFinish.apply(self, [event, file_count]) + }, + onStartOne: function(event, file_name, index, file_count) { + + }, + onFinishOne: function(event, response, name, number, total) { return self.finishUpload(event,response,name,number,total);}, + onProgress: function(event, progress, name, number, total) { return self.onProgress(event,progress,name,number,total);}, + onError: function(event, name, error) { return self.onError(event,name,error);}, + beforeSend: function(form) { return self.beforeSend(form);}, + + chunkSize: this.options.chunk_size || 1024*1024, + + target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\File::ajax_upload"), + query: function(file) {return self.beforeSend(file);}, + // Disable checking for already uploaded chunks + testChunks: false + }; + } /** * Set a widget or DOM node as a HTML5 file drop target * diff --git a/api/js/etemplate/et2_widget_vfs.js b/api/js/etemplate/et2_widget_vfs.js index 3447f0bcb6..b7aeb2f40b 100644 --- a/api/js/etemplate/et2_widget_vfs.js +++ b/api/js/etemplate/et2_widget_vfs.js @@ -828,9 +828,6 @@ var et2_vfsUpload = /** @class */ (function (_super) { var _this = // Call the inherited constructor _super.call(this, _parent, _attrs, et2_core_inheritance_1.ClassWithAttributes.extendAttributes(et2_vfsUpload._attributes, _child || {})) || this; - _this.asyncOptions = { - target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_upload") - }; _this.list = null; jQuery(_this.node).addClass("et2_vfs"); if (!_this.options.path) { @@ -843,11 +840,19 @@ var et2_vfsUpload = /** @class */ (function (_super) { _this.list = jQuery(document.createElement('table')).appendTo(_this.node); return _this; } + /** + * Get any specific async upload options + */ + et2_vfsUpload.prototype.getAsyncOptions = function (self) { + return jQuery.extend({}, _super.prototype.getAsyncOptions.call(this, self), { + target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_upload") + }); + }; /** * If there is a file / files in the specified location, display them * Value is the information for the file[s] in the specified location. * - * @param {Object[]} _value + * @param {Object{}} _value */ et2_vfsUpload.prototype.set_value = function (_value) { // Remove previous @@ -859,8 +864,8 @@ var et2_vfsUpload = /** @class */ (function (_super) { this.progress.empty(); this.list.empty(); // Set new - if (typeof _value == 'object' && _value && _value.length) { - for (var i = 0; i < _value.length; i++) { + if (typeof _value == 'object' && _value && Object.keys(_value).length) { + for (var i in _value) { this._addFile(_value[i]); } } diff --git a/api/js/etemplate/et2_widget_vfs.ts b/api/js/etemplate/et2_widget_vfs.ts index f16b165bbd..2124c05e43 100644 --- a/api/js/etemplate/et2_widget_vfs.ts +++ b/api/js/etemplate/et2_widget_vfs.ts @@ -934,10 +934,6 @@ class et2_vfsUpload extends et2_file public static readonly legacyOptions : string[] = ["mime"]; - asyncOptions : {target : any} = { - target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_upload") - }; - list : JQuery = null; /** @@ -966,11 +962,21 @@ class et2_vfsUpload extends et2_file this.list = jQuery(document.createElement('table')).appendTo(this.node); } + /** + * Get any specific async upload options + */ + getAsyncOptions(self) + { + return jQuery.extend({},super.getAsyncOptions(self),{ + target: egw.ajaxUrl("EGroupware\\Api\\Etemplate\\Widget\\Vfs::ajax_upload") + }); + } + /** * If there is a file / files in the specified location, display them * Value is the information for the file[s] in the specified location. * - * @param {Object[]} _value + * @param {Object{}} _value */ set_value(_value) { // Remove previous @@ -984,9 +990,9 @@ class et2_vfsUpload extends et2_file this.list.empty(); // Set new - if(typeof _value == 'object' && _value && _value.length) + if(typeof _value == 'object' && _value && Object.keys(_value).length) { - for(var i = 0; i < _value.length; i++) + for(let i in _value) { this._addFile(_value[i]); } diff --git a/api/src/Etemplate/Widget/Vfs.php b/api/src/Etemplate/Widget/Vfs.php index c60d6e9463..ca38235fe5 100644 --- a/api/src/Etemplate/Widget/Vfs.php +++ b/api/src/Etemplate/Widget/Vfs.php @@ -346,7 +346,7 @@ class Vfs extends File { if(Api\Vfs::file_exists(self::get_vfs_path($id) . $relpath)) {} }*/ - parent::validate($cname, $content, $validated); + parent::validate($cname, $expand, $content, $validated); break; } if (true) $valid = $value;