From 6ccde10a9658aa0155a51d7361c4ebee2826f76d Mon Sep 17 00:00:00 2001 From: Alan Knowles Date: Wed, 2 Jun 2021 15:00:40 +0800 Subject: [PATCH] Fix #6790 - Upload Button --- Roo/bootstrap/ButtonUploader.js | 167 ++++++++++++++++++++++++++++++ buildSDK/dependancy_bootstrap.txt | 3 + examples/bootstrap/dashboard1.bjs | 20 ++-- examples/bootstrap/dashboard1.js | 8 +- roojs-bootstrap-debug.js | 166 +++++++++++++++++++++++++++++ roojs-bootstrap.js | 5 + 6 files changed, 353 insertions(+), 16 deletions(-) create mode 100644 Roo/bootstrap/ButtonUploader.js diff --git a/Roo/bootstrap/ButtonUploader.js b/Roo/bootstrap/ButtonUploader.js new file mode 100644 index 0000000000..e392eea3f9 --- /dev/null +++ b/Roo/bootstrap/ButtonUploader.js @@ -0,0 +1,167 @@ + +/* +* Licence: LGPL +*/ + +/** + * @class Roo.bootstrap.ButtonUploader + * @extends Roo.bootstrap.Button + * Bootstrap Button Uploader class - it's a button which when you add files to it + * + * + * @cfg {Number} errorTimeout default 3000 + * @cfg {Array} images an array of ?? Img objects ??? when loading existing files.. + * @cfg {Array} html The button text. + + * + * @constructor + * Create a new CardUploader + * @param {Object} config The config object + */ + +Roo.bootstrap.ButtonUploader = function(config){ + + + + Roo.bootstrap.ButtonUploader.superclass.constructor.call(this, config); + + + this.addEvents({ + // raw events + /** + * @event beforeselect + * When button is pressed, before show upload files dialog is shown + * @param {Roo.bootstrap.UploaderButton} this + * + */ + 'beforeselect' : true, + /** + * @event fired when files have been selected, + * When a the download link is clicked + * @param {Roo.bootstrap.Card} this + * @param {Object} The image information data contains + */ + 'uploaded' : true + + }); +}; + +Roo.extend(Roo.bootstrap.ButtonUploader, Roo.bootstrap.Button, { + + + errorTimeout : 3000, + + images : false, + + fileCollection : false, + allowBlank : true, + + getAutoCreate : function() + { + + + return { + cls :'div' , + cn : [ + Roo.bootstrap.Button.prototype.getAutoCreate.call(this), + { + tag: 'input', + multiple : 'multiple', + type : 'file', + cls : 'd-none roo-card-upload-selector' + + } + + + ] + }; + + + }, + + + initEvents : function() + { + + Roo.bootstrap.Button.prototype.initEvents.call(this); + + + + + + this.urlAPI = (window.createObjectURL && window) || + (window.URL && URL.revokeObjectURL && URL) || + (window.webkitURL && webkitURL); + + + + + this.selectorEl = this.el.select('.roo-card-upload-selector', true).first(); + + this.selectorEl.on('change', this.onFileSelected, this); + + + + }, + + + onClick : function(e) + { + e.preventDefault(); + + if ( this.fireEvent('beforeselect', this) === false) { + return; + } + + this.selectorEl.dom.click(); + + }, + + onFileSelected : function(e) + { + e.preventDefault(); + + if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){ + return; + } + + Roo.each(this.selectorEl.dom.files, function(file){ + var url = this.urlAPI.createObjectURL(file); // not sure... + this.fireEvent('uploaded', this, [file, url]); + }, this); + + }, + + + + + /** + * addCard - add an Attachment to the uploader + * @param data - the data about the image to upload + * + * { + id : 123 + title : "Title of file", + is_uploaded : false, + src : "http://.....", + srcfile : { the File upload object }, + mimetype : file.type, + preview : false, + is_deleted : 0 + .. any other data... + } + * + * + */ + + reset: function() + { + + this.selectorEl + } + + + + +}); + \ No newline at end of file diff --git a/buildSDK/dependancy_bootstrap.txt b/buildSDK/dependancy_bootstrap.txt index 75b79e7537..e151ff2fd0 100644 --- a/buildSDK/dependancy_bootstrap.txt +++ b/buildSDK/dependancy_bootstrap.txt @@ -18,6 +18,9 @@ Roo.bootstrap.Card Roo.bootstrap.CardHeader Roo.bootstrap.CardFooter Roo.bootstrap.CardImageTop +Roo.bootstrap.ButtonUploader + + Roo.bootstrap.Img Roo.bootstrap.Link diff --git a/examples/bootstrap/dashboard1.bjs b/examples/bootstrap/dashboard1.bjs index c41cbea651..79ab753346 100644 --- a/examples/bootstrap/dashboard1.bjs +++ b/examples/bootstrap/dashboard1.bjs @@ -9,7 +9,6 @@ "dbd7790bcd23fde7607101ef6a633779" : "http://", "9dffbf69ffba8bc38bc4e01abf4b1675" : "Text", "680e083786e18d3b9bd07bffd61dc5dc" : "after : <i class="fa fa-ambulance"></i> before : <i class="fa fa-dollar"></i>", - "bc6d090c772eedbd8e59e273620830c6" : "File Input", "f6b6d9142474aba10b39e88cf4e06f6e" : "before : @", "7c4d0cf56e05ed67ec50246c517e149b" : "md 3", "cb6b36c6d62d94b76628a4543517f89b" : "md 4", @@ -26,6 +25,7 @@ "ac8f3751f51c35383892f7a1684e35ea" : "disabled = true", "8ac5836f3de7379d49bc60dcd36913c7" : "Input with Error", "cb76b3c00a2436a2a0d57f1282cbd66a" : "after : <i class="fa fa-after"></i>", + "dc8f50091cddc5183be3a5b5f774912a" : "Upload a file", "fd249a0c28275ebf9d4c8464ca2225cf" : "ComboBox", "5485e0b19975fe1d4400e35162a7c099" : "Quick Example", "c4ca4238a0b923820dcc509a6f75849b" : "1", @@ -76,8 +76,8 @@ "items" : [ { "String cls" : "header", - "xtype" : "Container", "tag" : "header", + "xtype" : "Container", "* xinclude" : "Dashboard.Header1", "$ xns" : "Roo.bootstrap" }, @@ -174,10 +174,8 @@ "String vtype" : "email" }, { - "xtype" : "Input", - "string placeholder" : "Enter email", - "String inputType" : "file", - "String fieldLabel" : "File Input", + "xtype" : "ButtonUploader", + "string html" : "Upload a file", "$ xns" : "Roo.bootstrap" }, { @@ -366,8 +364,8 @@ }, { "xtype" : "Header", - "$ xns" : "Roo.bootstrap", "Number level" : 4, + "$ xns" : "Roo.bootstrap", "String html" : "With Icons" }, { @@ -394,8 +392,8 @@ }, { "xtype" : "Header", - "Number level" : 4, "$ xns" : "Roo.bootstrap", + "Number level" : 4, "String html" : "With checkbox and radio" }, { @@ -421,8 +419,8 @@ }, { "xtype" : "Header", - "$ xns" : "Roo.bootstrap", "Number level" : 4, + "$ xns" : "Roo.bootstrap", "String html" : "With buttons" }, { @@ -541,8 +539,8 @@ }, { "xtype" : "TextArea", - "$ xns" : "Roo.bootstrap", - "String fieldLabel" : "Textarea" + "String fieldLabel" : "Textarea", + "$ xns" : "Roo.bootstrap" }, { "xtype" : "TextArea", diff --git a/examples/bootstrap/dashboard1.js b/examples/bootstrap/dashboard1.js index 92815f36a4..74ec81392b 100644 --- a/examples/bootstrap/dashboard1.js +++ b/examples/bootstrap/dashboard1.js @@ -8,7 +8,6 @@ dashboard1 = new Roo.XComponent({ 'dbd7790bcd23fde7607101ef6a633779' :"http://", '9dffbf69ffba8bc38bc4e01abf4b1675' :"Text", '680e083786e18d3b9bd07bffd61dc5dc' :"after : <i class="fa fa-ambulance"></i> before : <i class="fa fa-dollar"></i>", - 'bc6d090c772eedbd8e59e273620830c6' :"File Input", 'f6b6d9142474aba10b39e88cf4e06f6e' :"before : @", '7c4d0cf56e05ed67ec50246c517e149b' :"md 3", 'cb6b36c6d62d94b76628a4543517f89b' :"md 4", @@ -25,6 +24,7 @@ dashboard1 = new Roo.XComponent({ 'ac8f3751f51c35383892f7a1684e35ea' :"disabled = true", '8ac5836f3de7379d49bc60dcd36913c7' :"Input with Error", 'cb76b3c00a2436a2a0d57f1282cbd66a' :"after : <i class="fa fa-after"></i>", + 'dc8f50091cddc5183be3a5b5f774912a' :"Upload a file", 'fd249a0c28275ebf9d4c8464ca2225cf' :"ComboBox", '5485e0b19975fe1d4400e35162a7c099' :"Quick Example", 'c4ca4238a0b923820dcc509a6f75849b' :"1", @@ -199,10 +199,8 @@ dashboard1 = new Roo.XComponent({ '|xns' : 'Roo.bootstrap' }, { - xtype : 'Input', - fieldLabel : _this._strings['bc6d090c772eedbd8e59e273620830c6'] /* File Input */, - inputType : 'file', - placeholder : _this._strings['c3d8baf1b9da3d6922aea0057717a0b7'] /* Enter email */, + xtype : 'ButtonUploader', + html : _this._strings['dc8f50091cddc5183be3a5b5f774912a'] /* Upload a file */, xns : Roo.bootstrap, '|xns' : 'Roo.bootstrap' }, diff --git a/roojs-bootstrap-debug.js b/roojs-bootstrap-debug.js index 72b6b0d3ef..86cf32beaf 100644 --- a/roojs-bootstrap-debug.js +++ b/roojs-bootstrap-debug.js @@ -2848,6 +2848,172 @@ Roo.extend(Roo.bootstrap.CardImageTop, Roo.bootstrap.Element, { + +/* +* Licence: LGPL +*/ + +/** + * @class Roo.bootstrap.ButtonUploader + * @extends Roo.bootstrap.Button + * Bootstrap Button Uploader class - it's a button which when you add files to it + * + * + * @cfg {Number} errorTimeout default 3000 + * @cfg {Array} images an array of ?? Img objects ??? when loading existing files.. + * @cfg {Array} html The button text. + + * + * @constructor + * Create a new CardUploader + * @param {Object} config The config object + */ + +Roo.bootstrap.ButtonUploader = function(config){ + + + + Roo.bootstrap.ButtonUploader.superclass.constructor.call(this, config); + + + this.addEvents({ + // raw events + /** + * @event beforeselect + * When button is pressed, before show upload files dialog is shown + * @param {Roo.bootstrap.UploaderButton} this + * + */ + 'beforeselect' : true, + /** + * @event fired when files have been selected, + * When a the download link is clicked + * @param {Roo.bootstrap.Card} this + * @param {Object} The image information data contains + */ + 'uploaded' : true + + }); +}; + +Roo.extend(Roo.bootstrap.ButtonUploader, Roo.bootstrap.Button, { + + + errorTimeout : 3000, + + images : false, + + fileCollection : false, + allowBlank : true, + + getAutoCreate : function() + { + + + return { + cls :'div' , + cn : [ + Roo.bootstrap.Button.prototype.getAutoCreate.call(this), + { + tag: 'input', + multiple : 'multiple', + type : 'file', + cls : 'd-none roo-card-upload-selector' + + } + + + ] + }; + + + }, + + + initEvents : function() + { + + Roo.bootstrap.Button.prototype.initEvents.call(this); + + + + + + this.urlAPI = (window.createObjectURL && window) || + (window.URL && URL.revokeObjectURL && URL) || + (window.webkitURL && webkitURL); + + + + + this.selectorEl = this.el.select('.roo-card-upload-selector', true).first(); + + this.selectorEl.on('change', this.onFileSelected, this); + + + + }, + + + onClick : function(e) + { + e.preventDefault(); + + if ( this.fireEvent('beforeselect', this) === false) { + return; + } + + this.selectorEl.dom.click(); + + }, + + onFileSelected : function(e) + { + e.preventDefault(); + + if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){ + return; + } + + Roo.each(this.selectorEl.dom.files, function(file){ + var url = this.urlAPI.createObjectURL(file); // not sure... + this.fireEvent('uploaded', this, [file, url]); + }, this); + + }, + + + + + /** + * addCard - add an Attachment to the uploader + * @param data - the data about the image to upload + * + * { + id : 123 + title : "Title of file", + is_uploaded : false, + src : "http://.....", + srcfile : { the File upload object }, + mimetype : file.type, + preview : false, + is_deleted : 0 + .. any other data... + } + * + * + */ + + reset: function() + { + + this.selectorEl + } + + + + +}); /* * - LGPL * diff --git a/roojs-bootstrap.js b/roojs-bootstrap.js index 2f3837ca8e..0e3ecf0894 100644 --- a/roojs-bootstrap.js +++ b/roojs-bootstrap.js @@ -120,6 +120,11 @@ Roo.bootstrap.CardHeader=function(A){Roo.bootstrap.CardHeader.superclass.constru Roo.bootstrap.CardFooter=function(A){Roo.bootstrap.CardFooter.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.CardFooter,Roo.bootstrap.Element,{container_method:'getCardFooter'}); // Roo/bootstrap/CardImageTop.js Roo.bootstrap.CardImageTop=function(A){Roo.bootstrap.CardImageTop.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.CardImageTop,Roo.bootstrap.Element,{container_method:'getCardImageTop'}); +// Roo/bootstrap/ButtonUploader.js +Roo.bootstrap.ButtonUploader=function(A){Roo.bootstrap.ButtonUploader.superclass.constructor.call(this,A);this.addEvents({'beforeselect':true,'uploaded':true});};Roo.extend(Roo.bootstrap.ButtonUploader,Roo.bootstrap.Button,{errorTimeout:3000,images:false,fileCollection:false,allowBlank:true,getAutoCreate:function(){return {cls:'div',cn:[Roo.bootstrap.Button.prototype.getAutoCreate.call(this),{tag:'input',multiple:'multiple',type:'file',cls:'d-none roo-card-upload-selector'} +]};},initEvents:function(){Roo.bootstrap.Button.prototype.initEvents.call(this);this.urlAPI=(window.createObjectURL&&window)||(window.URL&&URL.revokeObjectURL&&URL)||(window.webkitURL&&webkitURL);this.selectorEl=this.el.select('.roo-card-upload-selector',true).first(); +this.selectorEl.on('change',this.onFileSelected,this);},onClick:function(e){e.preventDefault();if(this.fireEvent('beforeselect',this)===false){return;}this.selectorEl.dom.click();},onFileSelected:function(e){e.preventDefault();if(typeof(this.selectorEl.dom.files)=='undefined'||!this.selectorEl.dom.files.length){return; +}Roo.each(this.selectorEl.dom.files,function(A){var B=this.urlAPI.createObjectURL(A);this.fireEvent('uploaded',this,[A,B]);},this);},reset:function(){this.selectorEl}}); // Roo/bootstrap/Img.js Roo.bootstrap.Img=function(A){Roo.bootstrap.Img.superclass.constructor.call(this,A);this.addEvents({"click":true});};Roo.extend(Roo.bootstrap.Img,Roo.bootstrap.Component,{imgResponsive:true,border:'',src:'about:blank',href:false,target:false,xsUrl:'',smUrl:'',mdUrl:'',lgUrl:'',getAutoCreate:function(){if(this.src||(!this.xsUrl&&!this.smUrl&&!this.mdUrl&&!this.lgUrl)){return this.createSingleImg(); }var A={tag:'div',cls:'roo-image-responsive-group',cn:[]};var B=this;Roo.each(['xs','sm','md','lg'],function(C){if(!B[C+'Url']){return;}var D={tag:'img',cls:(B.imgResponsive)?'img-responsive':'',html:B.html||A.html,src:B[C+'Url']};D.cls+=' roo-image-responsive-'+C; -- 2.39.2