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} thumbSize default 300
16 * @cfg {String} fieldLabel
17 * @cfg {Number} labelWidth default 4
18 * @cfg {String} labelAlign (left|top) default left
19 * @cfg {Boolean} editable (true|false) allow edit when upload a image default true
22 * Create a new DocumentManager
23 * @param {Object} config The config object
26 Roo.bootstrap.DocumentManager = function(config){
27 Roo.bootstrap.DocumentManager.superclass.constructor.call(this, config);
32 * Fire when initial the DocumentManager
33 * @param {Roo.bootstrap.DocumentManager} this
38 * inspect selected file
39 * @param {Roo.bootstrap.DocumentManager} this
45 * Fire when xhr load exception
46 * @param {Roo.bootstrap.DocumentManager} this
47 * @param {XMLHttpRequest} xhr
52 * prepare the form data
53 * @param {Roo.bootstrap.DocumentManager} this
54 * @param {Object} formData
59 * Fire when remove the file
60 * @param {Roo.bootstrap.DocumentManager} this
61 * @param {Object} file
66 * Fire after refresh the file
67 * @param {Roo.bootstrap.DocumentManager} this
72 * Fire after click the image
73 * @param {Roo.bootstrap.DocumentManager} this
74 * @param {Object} file
79 * Fire when upload a image and editable set to true
80 * @param {Roo.bootstrap.DocumentManager} this
81 * @param {Object} file
85 * @event beforeselectfile
86 * Fire before select file
87 * @param {Roo.bootstrap.DocumentManager} this
89 "beforeselectfile" : true,
92 * Fire before process file
93 * @param {Roo.bootstrap.DocumentManager} this
94 * @param {Object} file
101 Roo.extend(Roo.bootstrap.DocumentManager, Roo.bootstrap.Component, {
110 paramName : 'imageUpload',
117 getAutoCreate : function()
119 var managerWidget = {
121 cls : 'roo-document-manager',
125 cls : 'roo-document-manager-selector',
130 cls : 'roo-document-manager-uploader',
134 cls : 'roo-document-manager-upload-btn',
135 html : '<i class="fa fa-plus"></i>'
146 cls : 'column col-md-12',
151 if(this.fieldLabel.length){
156 cls : 'column col-md-12',
157 html : this.fieldLabel
161 cls : 'column col-md-12',
166 if(this.labelAlign == 'left'){
170 cls : 'column col-md-' + this.labelWidth,
171 html : this.fieldLabel
175 cls : 'column col-md-' + (12 - this.labelWidth),
185 cls : 'row clearfix',
193 initEvents : function()
195 this.managerEl = this.el.select('.roo-document-manager', true).first();
196 this.managerEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
198 this.selectorEl = this.el.select('.roo-document-manager-selector', true).first();
199 this.selectorEl.setHeight('0px');
200 // this.selectorEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
201 this.selectorEl.hide();
204 this.selectorEl.attr('multiple', 'multiple');
207 this.selectorEl.on('change', this.onFileSelected, this);
209 this.uploader = this.el.select('.roo-document-manager-uploader', true).first();
210 this.uploader.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
212 this.uploader.on('click', this.onUploaderClick, this);
214 this.renderProgressDialog();
218 window.addEventListener("resize", function() { _this.refresh(); } );
220 this.fireEvent('initial', this);
223 renderProgressDialog : function()
227 this.progressDialog = new Roo.bootstrap.Modal({
228 cls : 'roo-document-manager-progress-dialog',
239 btnclick : function() {
240 _this.uploadCancel();
246 this.progressDialog.render(Roo.get(document.body));
248 this.progress = new Roo.bootstrap.Progress({
249 cls : 'roo-document-manager-progress',
254 this.progress.render(this.progressDialog.getChildContainer());
256 this.progressBar = new Roo.bootstrap.ProgressBar({
257 cls : 'roo-document-manager-progress-bar',
264 this.progressBar.render(this.progress.getChildContainer());
267 onUploaderClick : function(e)
271 if(this.fireEvent('beforeselectfile', this) != false){
272 this.selectorEl.dom.click();
277 onFileSelected : function(e)
281 if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
285 Roo.each(this.selectorEl.dom.files, function(file){
286 if(this.fireEvent('inspect', this, file) != false){
287 this.files.push(file);
297 this.selectorEl.dom.value = '';
299 if(!this.files.length){
303 if(this.boxes > 0 && this.files.length > this.boxes){
304 this.files = this.files.slice(0, this.boxes);
307 this.uploader.show();
309 if(this.boxes > 0 && this.files.length > this.boxes - 1){
310 this.uploader.hide();
319 Roo.each(this.files, function(file){
321 if(typeof(file.id) != 'undefined' && file.id * 1 > 0){
322 var f = this.renderPreview(file);
327 if(file.type.indexOf('image') != -1){
331 }).createDelegate(this)
340 }).createDelegate(this)
347 this.delegates = this.delegates.concat(docs);
349 if(!this.delegates.length){
354 this.progressBar.aria_valuemax = this.delegates.length;
363 if(!this.delegates.length){
364 this.progressDialog.hide();
369 var delegate = this.delegates.shift();
371 this.progressDialog.show();
373 this.progressDialog.setTitle((this.progressBar.aria_valuemax - this.delegates.length) + ' / ' + this.progressBar.aria_valuemax);
375 this.progressBar.update(this.progressBar.aria_valuemax - this.delegates.length);
382 this.uploader.show();
384 if(this.boxes > 0 && this.files.length > this.boxes - 1){
385 this.uploader.hide();
388 Roo.isTouch ? this.closable(false) : this.closable(true);
390 this.fireEvent('refresh', this);
393 onRemove : function(e, el, o)
397 this.fireEvent('remove', this, o);
405 Roo.each(this.files, function(file){
406 if(typeof(file.id) == 'undefined' || file.id * 1 < 1 || file.id != o.id){
422 Roo.each(this.files, function(file){
427 file.target.remove();
436 onClick : function(e, el, o)
440 this.fireEvent('click', this, o);
444 closable : function(closable)
446 Roo.each(this.managerEl.select('.roo-document-manager-preview > button.close', true).elements, function(el){
448 el.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
460 xhrOnLoad : function(xhr)
462 Roo.each(this.managerEl.select('.roo-document-manager-loading', true).elements, function(el){
466 if (xhr.readyState !== 4) {
468 this.fireEvent('exception', this, xhr);
472 var response = Roo.decode(xhr.responseText);
474 if(!response.success){
476 this.fireEvent('exception', this, xhr);
480 var file = this.renderPreview(response.data);
482 this.files.push(file);
488 xhrOnError : function()
490 Roo.log('xhr on error');
492 var response = Roo.decode(xhr.responseText);
499 process : function(file)
501 if(this.fireEvent('process', this, file) !== false){
502 if(this.editable && file.type.indexOf('image') != -1){
503 this.fireEvent('edit', this, file);
507 this.uploadStart(file, false);
514 uploadStart : function(file, crop)
516 this.xhr = new XMLHttpRequest();
518 if(typeof(file.id) != 'undefined' && file.id * 1 > 0){
525 this.managerEl.createChild({
527 cls : 'roo-document-manager-loading',
532 cls : 'roo-document-manager-thumb',
533 html : '<i class="fa fa-circle-o-notch fa-spin"></i>'
539 this.xhr.open(this.method, this.url, true);
542 "Accept": "application/json",
543 "Cache-Control": "no-cache",
544 "X-Requested-With": "XMLHttpRequest"
547 for (var headerName in headers) {
548 var headerValue = headers[headerName];
550 this.xhr.setRequestHeader(headerName, headerValue);
556 this.xhr.onload = function()
558 _this.xhrOnLoad(_this.xhr);
561 this.xhr.onerror = function()
563 _this.xhrOnError(_this.xhr);
566 var formData = new FormData();
568 formData.append('returnHTML', 'NO');
571 formData.append('crop', crop);
574 formData.append(this.paramName, file, file.name);
576 if(this.fireEvent('prepare', this, formData) != false){
577 this.xhr.send(formData);
581 uploadCancel : function()
587 Roo.each(this.managerEl.select('.roo-document-manager-loading', true).elements, function(el){
594 renderPreview : function(file)
596 if(typeof(file.target) != 'undefined' && file.target){
600 var previewEl = this.managerEl.createChild({
602 cls : 'roo-document-manager-preview',
606 tooltip : file.filename,
607 cls : 'roo-document-manager-thumb',
608 html : '<img src="' + baseURL +'/Images/Thumb/' + this.thumbSize + '/' + file.id + '/' + file.filename + '">'
613 html : '<i class="fa fa-times-circle"></i>'
618 var close = previewEl.select('button.close', true).first();
620 close.on('click', this.onRemove, this, file);
622 file.target = previewEl;
624 var image = previewEl.select('img', true).first();
628 image.dom.addEventListener("load", function(){ _this.onPreviewLoad(file, image); });
630 image.on('click', this.onClick, this, file);
636 onPreviewLoad : function(file, image)
638 if(typeof(file.target) == 'undefined' || !file.target){
642 var width = image.dom.naturalWidth || image.dom.width;
643 var height = image.dom.naturalHeight || image.dom.height;
646 file.target.addClass('wide');
650 file.target.addClass('tall');
655 uploadFromSource : function(file, crop)
657 this.xhr = new XMLHttpRequest();
659 this.managerEl.createChild({
661 cls : 'roo-document-manager-loading',
666 cls : 'roo-document-manager-thumb',
667 html : '<i class="fa fa-circle-o-notch fa-spin"></i>'
673 this.xhr.open(this.method, this.url, true);
676 "Accept": "application/json",
677 "Cache-Control": "no-cache",
678 "X-Requested-With": "XMLHttpRequest"
681 for (var headerName in headers) {
682 var headerValue = headers[headerName];
684 this.xhr.setRequestHeader(headerName, headerValue);
690 this.xhr.onload = function()
692 _this.xhrOnLoad(_this.xhr);
695 this.xhr.onerror = function()
697 _this.xhrOnError(_this.xhr);
700 var formData = new FormData();
702 formData.append('returnHTML', 'NO');
704 formData.append('crop', crop);
706 if(typeof(file.filename) != 'undefined'){
707 formData.append('filename', file.filename);
710 if(typeof(file.mimetype) != 'undefined'){
711 formData.append('mimetype', file.mimetype);
714 if(this.fireEvent('prepare', this, formData) != false){
715 this.xhr.send(formData);