7 * @class Roo.bootstrap.DocumentManager
8 * @extends Roo.bootstrap.Component
9 * Bootstrap DocumentManager class
10 * @cfg {String} paramName default 'imageUpload'
11 * @cfg {String} method default POST
12 * @cfg {String} url action url
13 * @cfg {Number} boxes number of boxes, 0 is no limit.. default 0
14 * @cfg {Boolean} multiple multiple upload default true
15 * @cfg {Number} minWidth default 300
16 * @cfg {Number} minHeight default 300
17 * @cfg {Number} thumbSize default 300
18 * @cfg {String} fieldLabel
19 * @cfg {Number} labelWidth default 4
20 * @cfg {String} labelAlign (left|top) default left
21 * @cfg {Boolean} editable (true|false) allow edit when upload a image default true
24 * Create a new DocumentManager
25 * @param {Object} config The config object
28 Roo.bootstrap.DocumentManager = function(config){
29 Roo.bootstrap.DocumentManager.superclass.constructor.call(this, config);
34 * Fire when initial the DocumentManager
35 * @param {Roo.bootstrap.DocumentManager} this
40 * inspect selected file
41 * @param {Roo.bootstrap.DocumentManager} this
47 * Fire when xhr load exception
48 * @param {Roo.bootstrap.DocumentManager} this
49 * @param {XMLHttpRequest} xhr
54 * prepare the form data
55 * @param {Roo.bootstrap.DocumentManager} this
56 * @param {Object} formData
61 * Fire when remove the file
62 * @param {Roo.bootstrap.DocumentManager} this
63 * @param {Object} file
68 * Fire after refresh the file
69 * @param {Roo.bootstrap.DocumentManager} this
74 * Fire after click the image
75 * @param {Roo.bootstrap.DocumentManager} this
76 * @param {Object} file
81 * Fire when upload a image and editable set to true
82 * @param {Roo.bootstrap.DocumentManager} this
83 * @param {Object} file
87 * @event beforeselectfile
88 * Fire before select file
89 * @param {Roo.bootstrap.DocumentManager} this
91 "beforeselectfile" : true
96 Roo.extend(Roo.bootstrap.DocumentManager, Roo.bootstrap.Component, {
107 paramName : 'imageUpload',
114 getAutoCreate : function()
116 var managerWidget = {
118 cls : 'roo-document-manager',
122 cls : 'roo-document-manager-selector',
127 cls : 'roo-document-manager-uploader',
131 cls : 'roo-document-manager-upload-btn',
132 html : '<i class="fa fa-plus"></i>'
143 cls : 'column col-md-12',
148 if(this.fieldLabel.length){
153 cls : 'column col-md-12',
154 html : this.fieldLabel
158 cls : 'column col-md-12',
163 if(this.labelAlign == 'left'){
167 cls : 'column col-md-' + this.labelWidth,
168 html : this.fieldLabel
172 cls : 'column col-md-' + (12 - this.labelWidth),
182 cls : 'row clearfix',
190 initEvents : function()
192 this.managerEl = this.el.select('.roo-document-manager', true).first();
193 this.managerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
195 this.selectorEl = this.el.select('.roo-document-manager-selector', true).first();
196 this.selectorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
197 this.selectorEl.hide();
200 this.selectorEl.attr('multiple', 'multiple');
203 this.selectorEl.on('change', this.onFileSelected, this);
205 this.uploader = this.el.select('.roo-document-manager-uploader', true).first();
206 this.uploader.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
208 this.uploader.on('click', this.onUploaderClick, this);
210 this.renderProgressDialog();
214 window.addEventListener("resize", function() { _this.refresh(); } );
216 this.fireEvent('initial', this);
219 renderProgressDialog : function()
223 this.progressDialog = new Roo.bootstrap.Modal({
224 cls : 'roo-document-manager-progress-dialog',
235 btnclick : function() {
236 _this.uploadCancel();
242 this.progressDialog.render(Roo.get(document.body));
244 this.progress = new Roo.bootstrap.Progress({
245 cls : 'roo-document-manager-progress',
250 this.progress.render(this.progressDialog.getChildContainer());
252 this.progressBar = new Roo.bootstrap.ProgressBar({
253 cls : 'roo-document-manager-progress-bar',
260 this.progressBar.render(this.progress.getChildContainer());
263 onUploaderClick : function(e)
267 if(this.fireEvent('beforeselectfile', this) != false){
268 this.selectorEl.dom.click();
273 onFileSelected : function(e)
277 if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
281 Roo.each(this.selectorEl.dom.files, function(file){
282 if(this.fireEvent('inspect', this, file) != false){
283 this.files.push(file);
293 this.selectorEl.dom.value = '';
295 if(!this.files.length){
299 if(this.boxes > 0 && this.files.length > this.boxes){
300 this.files = this.files.slice(0, this.boxes);
303 this.uploader.show();
305 if(this.boxes > 0 && this.files.length > this.boxes - 1){
306 this.uploader.hide();
313 Roo.each(this.files, function(file){
315 if(typeof(file.id) != 'undefined' && file.id * 1 > 0){
316 var f = this.renderPreview(file);
324 }).createDelegate(this)
331 if(!this.delegates.length){
336 this.progressBar.aria_valuemax = this.delegates.length;
345 if(!this.delegates.length){
346 this.progressDialog.hide();
351 var delegate = this.delegates.shift();
353 this.progressDialog.show();
355 this.progressDialog.setTitle((this.progressBar.aria_valuemax - this.delegates.length) + ' / ' + this.progressBar.aria_valuemax);
357 this.progressBar.update(this.progressBar.aria_valuemax - this.delegates.length);
364 this.uploader.show();
366 if(this.files.length > this.boxes - 1){
367 this.uploader.hide();
370 Roo.isTouch ? this.closable(false) : this.closable(true);
372 this.fireEvent('refresh', this);
375 onRemove : function(e, el, o)
379 this.fireEvent('remove', this, o);
387 Roo.each(this.files, function(file){
388 if(typeof(file.id) == 'undefined' || file.id * 1 < 1 || file.id != o.id){
402 onClick : function(e, el, o)
406 this.fireEvent('click', this, o);
410 closable : function(closable)
412 Roo.each(this.managerEl.select('.roo-document-manager-preview > button.close', true).elements, function(el){
414 el.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
426 xhrOnLoad : function(xhr)
428 Roo.each(this.managerEl.select('.roo-document-manager-loading', true).elements, function(el){
432 if (xhr.readyState !== 4) {
434 this.fireEvent('exception', this, xhr);
438 var response = Roo.decode(xhr.responseText);
440 if(!response.success){
442 this.fireEvent('exception', this, xhr);
446 var file = this.renderPreview(response.data);
448 this.files.push(file);
454 xhrOnError : function()
456 Roo.log('xhr on error');
458 var response = Roo.decode(xhr.responseText);
465 process : function(file)
467 if(this.editable && file.type.indexOf('image') != -1){
468 this.fireEvent('edit', this, file);
472 this.uploadStart(file, false);
477 uploadStart : function(file, crop)
479 this.xhr = new XMLHttpRequest();
481 if(typeof(file.id) != 'undefined' && file.id * 1 > 0){
488 this.managerEl.createChild({
490 cls : 'roo-document-manager-loading',
495 cls : 'roo-document-manager-thumb',
496 html : '<i class="fa fa-circle-o-notch fa-spin"></i>'
502 this.xhr.open(this.method, this.url, true);
505 "Accept": "application/json",
506 "Cache-Control": "no-cache",
507 "X-Requested-With": "XMLHttpRequest"
510 for (var headerName in headers) {
511 var headerValue = headers[headerName];
513 this.xhr.setRequestHeader(headerName, headerValue);
519 this.xhr.onload = function()
521 _this.xhrOnLoad(_this.xhr);
524 this.xhr.onerror = function()
526 _this.xhrOnError(_this.xhr);
529 var formData = new FormData();
531 formData.append('returnHTML', 'NO');
534 formData.append('crop', crop);
537 formData.append(this.paramName, file, file.name);
539 if(this.fireEvent('prepare', this, formData) != false){
540 this.xhr.send(formData);
544 uploadCancel : function()
550 Roo.each(this.managerEl.select('.roo-document-manager-loading', true).elements, function(el){
557 renderPreview : function(file)
559 if(typeof(file.target) != 'undefined' && file.target){
563 var previewEl = this.managerEl.createChild({
565 cls : 'roo-document-manager-preview',
569 tooltip : file.filename,
570 cls : 'roo-document-manager-thumb',
571 html : '<img src="' + baseURL +'/Images/Thumb/' + this.thumbSize + '/' + file.id + '/' + file.filename + '">'
576 html : '<i class="fa fa-times-circle"></i>'
581 var close = previewEl.select('button.close', true).first();
583 close.on('click', this.onRemove, this, file);
585 file.target = previewEl;
587 var image = previewEl.select('img', true).first();
591 image.dom.addEventListener("load", function(){ _this.onPreviewLoad(file, image); });
593 image.on('click', this.onClick, this, file);
599 onPreviewLoad : function(file, image)
601 if(typeof(file.target) == 'undefined' || !file.target){
605 var width = image.dom.naturalWidth || image.dom.width;
606 var height = image.dom.naturalHeight || image.dom.height;
609 file.target.addClass('wide');
613 file.target.addClass('tall');