142cf148daafd0bb85a43fe92cc3750ef420098f
[roojs1] / Roo / bootstrap / CardUploader.js
1
2 /*
3 * Licence: LGPL
4 */
5
6 /**
7  * @class Roo.bootstrap.CardUploader
8  * @extends Roo.bootstrap.Button
9  * Bootstrap Card Uploader class - it's a button which when you add files to it, adds cards below with preview and the name...
10  * @cfg {Number} errorTimeout default 3000
11  * @cfg {Array}  images  an array of ?? Img objects ??? when loading existing files..
12  * @cfg {Array}  html The button text.
13
14  *
15  * @constructor
16  * Create a new CardUploader
17  * @param {Object} config The config object
18  */
19
20 Roo.bootstrap.CardUploader = function(config){
21     
22  
23     
24     Roo.bootstrap.CardUploader.superclass.constructor.call(this, config);
25     
26     
27     this.fileCollection   = new Roo.util.MixedCollection(false,function(r) {
28         return r.data.id
29      });
30     
31      this.addEvents({
32          // raw events
33         /**
34          * @event view
35          * When a image is clicked on - and needs to display a slideshow or similar..
36          * @param {Roo.bootstrap.Card} this
37          * @param {Object} The image information data 
38          *
39          */
40         'view' : true,
41          /**
42          * @event download
43          * When a the download link is clicked
44          * @param {Roo.bootstrap.Card} this
45          * @param {Object} The image information data  contains 
46          */
47         'download' : true
48         
49     });
50 };
51 };
52
53 Roo.extend(Roo.bootstrap.CardUploader, Roo.bootstrap.Input,  {
54     
55      
56     errorTimeout : 3000,
57      
58     images : false,
59    
60     fileCollection : false,
61     allowBlank : true,
62     
63     getAutoCreate : function()
64     {
65         
66         var cfg =  {
67             cls :'form-group' ,
68             cn : [
69                
70                 {
71                     tag: 'label',
72                    //cls : 'input-group-addon',
73                     html : this.fieldLabel
74
75                 },
76
77                 {
78                     tag: 'input',
79                     type : 'hidden',
80                     name : this.name,
81                     value : this.value,
82                     cls : 'd-none  form-control'
83                 },
84                 
85                 {
86                     tag: 'input',
87                     multiple : 'multiple',
88                     type : 'file',
89                     cls : 'd-none  roo-card-upload-selector'
90                 },
91                 
92                 {
93                     cls : 'roo-card-uploader-button-container w-100 mb-2'
94                 },
95                 {
96                     cls : 'card-columns roo-card-uploader-container'
97                 }
98
99             ]
100         };
101            
102          
103         return cfg;
104     },
105     
106     getChildContainer : function() /// what children are added to.
107     {
108         return this.containerEl;
109     },
110    
111     getButtonContainer : function() /// what children are added to.
112     {
113         return this.el.select(".roo-card-uploader-button-container").first();
114     },
115    
116     initEvents : function()
117     {
118         
119         Roo.bootstrap.Input.prototype.initEvents.call(this);
120         
121         var t = this;
122         this.addxtype({
123             xns: Roo.bootstrap,
124
125             xtype : 'Button',
126             container_method : 'getButtonContainer' ,            
127             html :  this.html, // fix changable?
128             cls : 'w-100 ',
129             listeners : {
130                 'click' : function(btn, e) {
131                     t.onClick(e);
132                 }
133             }
134         });
135         
136         
137         
138         
139         this.urlAPI = (window.createObjectURL && window) || 
140                                 (window.URL && URL.revokeObjectURL && URL) || 
141                                 (window.webkitURL && webkitURL);
142                         
143          
144          
145          
146         this.selectorEl = this.el.select('.roo-card-upload-selector', true).first();
147         
148         this.selectorEl.on('change', this.onFileSelected, this);
149         if (this.images) {
150             var t = this;
151             this.images.forEach(function(img) {
152                 t.addCard(img)
153             });
154             this.images = false;
155         }
156         this.containerEl = this.el.select('.roo-card-uploader-container', true).first();
157          
158        
159     },
160     
161    
162     onClick : function(e)
163     {
164         e.preventDefault();
165          
166         this.selectorEl.dom.click();
167          
168     },
169     
170     onFileSelected : function(e)
171     {
172         e.preventDefault();
173         
174         if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
175             return;
176         }
177         
178         Roo.each(this.selectorEl.dom.files, function(file){    
179             this.addFile(file);
180         }, this);
181          
182     },
183     
184       
185     
186       
187     
188     addFile : function(file)
189     {
190            
191         if(typeof(file) === 'string'){
192             throw "Add file by name?"; // should not happen
193             return;
194         }
195         
196         if(!file || !this.urlAPI){
197             return;
198         }
199         
200         // file;
201         // file.type;
202         
203         var _this = this;
204         
205         
206         var url = _this.urlAPI.createObjectURL( file);
207            
208         this.addCard({
209             id : Roo.bootstrap.CardUploader.ID--,
210             is_uploaded : false,
211             src : url,
212             srcfile : file,
213             title : file.name,
214             mimetype : file.type,
215             preview : false,
216             is_deleted : 0
217         });
218         
219     },
220     
221     /**
222      * addCard - add an Attachment to the uploader
223      * @param data - the data about the image to upload
224      *
225      * {
226           id : 123
227           title : "Title of file",
228           is_uploaded : false,
229           src : "http://.....",
230           srcfile : { the File upload object },
231           mimetype : file.type,
232           preview : false,
233           is_deleted : 0
234           .. any other data...
235         }
236      *
237      * 
238     */
239     
240     addCard : function (data)
241     {
242         // hidden input element?
243         // if the file is not an image...
244         //then we need to use something other that and header_image
245         var t = this;
246         //   remove.....
247         var footer = [
248             {
249                 xns : Roo.bootstrap,
250                 xtype : 'CardFooter',
251                  items: [
252                     {
253                         xns : Roo.bootstrap,
254                         xtype : 'Element',
255                         cls : 'd-flex',
256                         items : [
257                             
258                             {
259                                 xns : Roo.bootstrap,
260                                 xtype : 'Button',
261                                 html : String.format("<small>{0}</small>", data.title),
262                                 cls : 'col-10 text-left',
263                                 size: 'sm',
264                                 weight: 'link',
265                                 fa : 'download',
266                                 listeners : {
267                                     click : function() {
268                                      
269                                         t.fireEvent( "download", t, data );
270                                     }
271                                 }
272                             },
273                           
274                             {
275                                 xns : Roo.bootstrap,
276                                 xtype : 'Button',
277                                 style: 'max-height: 28px; ',
278                                 size : 'sm',
279                                 weight: 'danger',
280                                 cls : 'col-2',
281                                 fa : 'times',
282                                 listeners : {
283                                     click : function() {
284                                         t.removeCard(data.id)
285                                     }
286                                 }
287                             }
288                         ]
289                     }
290                     
291                 ] 
292             }
293             
294         ];
295         
296         var cn = this.addxtype(
297             {
298                  
299                 xns : Roo.bootstrap,
300                 xtype : 'Card',
301                 closeable : true,
302                 header : !data.mimetype.match(/image/) && !data.preview ? "Document": false,
303                 header_image : data.mimetype.match(/image/) ? data.src  : data.preview,
304                 header_image_fit_square: true, // fixme  - we probably need to use the 'Img' element to do stuff like this.
305                 data : data,
306                 html : false,
307                  
308                 items : footer,
309                 initEvents : function() {
310                     Roo.bootstrap.Card.prototype.initEvents.call(this);
311                     var card = this;
312                     this.imgEl = this.el.select('.card-img-top').first();
313                     if (this.imgEl) {
314                         this.imgEl.on('click', function() { t.fireEvent( "preview", t, data ); }, this);
315                         this.imgEl.set({ 'pointer' : 'cursor' });
316                                   
317                     }
318                     this.getCardFooter().addClass('p-1');
319                     
320                   
321                 }
322                 
323             }
324         );
325         // dont' really need ot update items.
326         // this.items.push(cn);
327         this.fileCollection.add(cn);
328         
329         if (!data.srcfile) {
330             this.updateInput();
331             return;
332         }
333             
334         var _t = this;
335         var reader = new FileReader();
336         reader.addEventListener("load", function() {  
337             data.srcdata =  reader.result;
338             _t.updateInput();
339         });
340         reader.readAsDataURL(data.srcfile);
341         
342         
343         
344     },
345     removeCard : function(id)
346     {
347         
348         var card  = this.fileCollection.get(id);
349         card.data.is_deleted = 1;
350         card.data.src = ''; /// delete the source - so it reduces size of not uploaded images etc.
351         //this.fileCollection.remove(card);
352         //this.items = this.items.filter(function(e) { return e != card });
353         // dont' really need ot update items.
354         card.el.dom.parentNode.removeChild(card.el.dom);
355         this.updateInput();
356
357         
358     },
359     reset: function()
360     {
361         this.fileCollection.each(function(card) {
362             if (card.el.dom && card.el.dom.parentNode) {
363                 card.el.dom.parentNode.removeChild(card.el.dom);
364             }
365         });
366         this.fileCollection.clear();
367         this.updateInput();
368     },
369     
370     updateInput : function()
371     {
372          var data = [];
373         this.fileCollection.each(function(e) {
374             data.push(e.data);
375             
376         });
377         this.inputEl().dom.value = JSON.stringify(data);
378         
379         
380         
381     }
382     
383     
384 });
385
386
387 Roo.bootstrap.CardUploader.ID = -1;