Files
ERP/sophal/js/form/form.input.binary.js

448 lines
12 KiB
JavaScript

/*
* Axelor Business Solutions
*
* Copyright (C) 2005-2019 Axelor (<http://axelor.com>).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
(function() {
"use strict";
var ui = angular.module('axelor.ui');
var BLANK = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
var META_FILE = "com.axelor.meta.db.MetaFile";
var META_JSON_RECORD = "com.axelor.meta.db.MetaJsonRecord";
function makeURL(model, field, recordOrId, version, scope) {
var value = recordOrId;
if (!value) return null;
var id = value.id ? value.id : value;
var ver = version;
if (ver === undefined || ver === null) ver = value.version;
if (ver === undefined || ver === null) ver = value.$version;
if (ver === undefined || ver === null) ver = (new Date()).getTime();
if (!id || id <= 0) return null;
var url = "ws/rest/" + model + "/" + id + "/" + field + "/download?v=" + ver;
if (scope && scope.record) {
var parentId = scope.record.id;
if (!parentId && scope.field && scope._jsonContext && scope._jsonContext.$record) {
parentId = scope._jsonContext.$record.id;
}
url += "&parentId=" + parentId + "&parentModel=" + scope._model;
}
return url;
}
ui.makeImageURL = makeURL;
ui.formInput('ImageLink', {
css: 'image-item',
cssClass: 'from-item image-item',
metaWidget: true,
controller: ['$scope', '$element', '$interpolate', function($scope, $element, $interpolate) {
$scope.parseText = function(text) {
if (!text) return BLANK;
if (!text.match(/{{.*?}}/)) {
return text;
}
return $interpolate(text)($scope.record);
};
}],
init: function(scope) {
var field = scope.field;
var width = field.width || 140;
var height = field.height || '100%';
scope.styles = [{
'width': width,
'max-width': '100%',
'max-height': '100%'
}, {
'width': width,
'height': height,
'max-width': '100%',
'max-height': '100%'
}];
if (field.noframe) {
_.extend(scope.styles[1], {
border: 0,
padding: 0,
background: 'none',
boxShadow: 'none'
});
}
},
link_readonly: function(scope, element, attrs, model) {
var image = element.children('img:first');
var update = scope.$render_readonly = function () {
if (scope.isReadonly()) {
image.get(0).src = scope.parseText(model.$viewValue) || BLANK;
}
};
scope.$watch("record.id", update);
scope.$watch("record.version", update);
scope.$watch("isReadonly()", update);
},
template_editable: '<input type="text">',
template_readonly:
'<div ng-style="styles[0]">'+
'<img class="img-polaroid" ng-style="styles[1]">'+
'</div>'
});
ui.formInput('Image', 'ImageLink', {
init: function(scope) {
this._super.apply(this, arguments);
var field = scope.field;
var isBinary = field.serverType === 'binary';
if (!isBinary && field.target !== META_FILE) {
throw new Error("Invalid field type for Image widget.");
}
scope.parseText = function (value) {
return scope.getLink(value);
};
scope.getLink = function (value) {
var record = scope.record || {};
var model = scope._model;
if (value === null) return BLANK;
if (isBinary) {
if (value) {
return value;
}
if (record.id) {
return makeURL(model, field.name, record, undefined, scope) + "&image=true";
}
return BLANK;
}
return value ? makeURL(META_FILE, "content", (value.id || value), value.version || value.$version, scope) : BLANK;
};
},
link_editable: function(scope, element, attrs, model) {
var field = scope.field;
var input = element.children('input:first');
var image = element.children('img:first');
var buttons = element.children('.btn-group');
var isBinary = field.serverType === 'binary';
var timer = null;
input.add(buttons).hide();
element.on('mouseenter', function (e) {
if (timer) clearTimeout(timer);
timer = setTimeout(function () {
buttons.slideDown();
}, 500);
});
element.on('mouseleave', function (e) {
if (timer) {
clearTimeout(timer);
timer = null;
}
buttons.slideUp();
});
scope.doSelect = function() {
input.click();
};
scope.doSave = function() {
var content = image.get(0).src;
if (content) {
window.open(content);
}
};
scope.doRemove = function() {
image.get(0).src = "";
input.val(null);
update(null);
};
input.change(function(e, ui) {
var file = input.get(0).files[0];
var uploadSize = +(axelor.config["file.upload.size"]) || 0;
// reset file selection
input.get(0).value = null;
if (!file) {
return;
}
if(uploadSize > 0 && file.size > 1048576 * uploadSize) {
return axelor.dialogs.say(_t("You are not allow to upload a file bigger than") + ' ' + uploadSize + 'MB');
}
if (!isBinary) {
return doUpload(file);
}
var reader = new FileReader();
reader.onload = function(e) {
update(e.target.result, file.name);
};
reader.readAsDataURL(file);
});
function doUpload(file) {
var ds = scope._dataSource._new(META_FILE);
var value = field.target === META_FILE ? (scope.getValue()||{}) : {};
var record = {
fileName: file.name,
fileType: file.type,
fileSize: file.size,
id: value.id,
version: value.version || value.$version
};
record.$upload = {
file: file
};
ds.save(record).success(function (saved) {
update(saved);
});
}
function doUpdate(value) {
image.get(0).src = scope.getLink(value);
model.$setViewValue(getData(value));
}
function update(value) {
scope.$applyAsync(function() {
doUpdate(value);
});
}
function getData(value) {
if (!value || isBinary) {
return value;
}
return {
id: value.id
};
}
var updateLink = scope.$render_editable = function() {
image.get(0).src = scope.getLink(model.$viewValue);
};
scope.$watch("record.id", updateLink);
scope.$watch("record.version", updateLink);
if (field.accept) {
input.attr('accept', field.accept);
}
},
template_editable:
'<div ng-style="styles[0]" class="image-wrapper">' +
'<input type="file" accept="image/*">' +
'<img class="img-polaroid" ng-style="styles[1]" style="display: inline-block;">' +
'<div class="btn-group">' +
'<button ng-click="doSelect()" class="btn" type="button"><i class="fa fa-arrow-circle-up"></i></button>' +
'<button ng-click="doRemove()" class="btn" type="button"><i class="fa fa-times"></i></button>' +
'</div>' +
'</div>'
});
ui.formInput('Binary', {
css: 'file-item',
cellCss: 'form-item file-item',
link: function(scope, element, attrs, model) {
var field = scope.field;
var input = element.children('input:first').hide();
scope.doSelect = function() {
input.click();
};
scope.doSave = function() {
var record = scope.record;
var model = scope._model;
var url = makeURL(model, field.name, record, undefined, scope);
ui.download(url, record.fileName || field.name);
};
scope.doRemove = function() {
var record = scope.record;
input.val(null);
model.$setViewValue(null);
record.$upload = null;
if(scope._model === META_FILE) {
record.fileName = null;
record.fileType = null;
}
record.fileSize = null;
};
scope.canDownload = function() {
var record = scope.record || {};
if (!record.id) return false;
if (scope._model === META_FILE) {
return !!record.fileName;
}
return true;
};
input.change(function(e) {
var file = input.get(0).files[0];
var record = scope.record;
// reset file selection
input.get(0).value = null;
if (file) {
record.$upload = {
field: field.name,
file: file
};
if(scope._model === META_FILE) {
record.fileName = file.name;
}
scope.$applyAsync(function() {
record.fileType = file.type;
record.fileSize = file.size;
});
}
});
if (field.accept) {
input.attr('accept', field.accept);
}
},
template_readonly: null,
template_editable: null,
template:
'<div>' +
'<input type="file">' +
'<div class="btn-group">' +
'<button ng-click="doSelect()" ng-show="!isReadonly()" class="btn" type="button"><i class="fa fa-arrow-circle-up"></i></button>' +
'<button ng-click="doSave()" ng-show="canDownload()" class="btn" type="button"><i class="fa fa-arrow-circle-down"></i></button>' +
'<button ng-click="doRemove()" ng-show="!isReadonly()" class="btn" type="button"><i class="fa fa-times"></i></button>' +
'</div>' +
'</div>'
});
ui.formInput('BinaryLink', {
css: 'file-item',
cellCss: 'form-item file-item',
metaWidget: true,
link: function(scope, element, attrs, model) {
var field = scope.field;
var input = element.children('input:first').hide();
if (field.target !== META_FILE) {
throw new Error("BinaryLink widget can be used with MetaFile field only.");
}
scope.doSelect = function() {
input.click();
};
scope.doRemove = function() {
input.val(null);
scope.setValue(null, true);
};
scope.canDownload = function() {
var value = model.$viewValue;
return value && value.id > 0;
};
scope.format = function (value) {
if (value) {
return value.fileName;
}
return value;
};
scope.doSave = function() {
var value = model.$viewValue;
var version = value ? (value.version || value.$version) : undefined;
var url = makeURL(META_FILE, "content", value, version, scope);
ui.download(url, scope.text);
};
input.change(function(e) {
var file = input.get(0).files[0];
// reset file selection
input.get(0).value = null;
if (!file) {
return;
}
var ds = scope._dataSource._new(META_FILE);
var value = scope.getValue() || {};
var record = _.extend({
fileName: file.name,
fileType: file.type,
fileSize: file.size
}, {
id: value.id,
version: value.version || value.$version
});
record.$upload = {
file: file
};
ds.save(record).success(function (rec) {
scope.setValue(rec, true);
});
});
if (field.accept) {
input.attr('accept', field.accept);
}
},
template_readonly: null,
template_editable: null,
template:
'<div>' +
'<input type="file">' +
'<div class="btn-group">' +
'<button ng-click="doSelect()" ng-show="!isReadonly()" class="btn" type="button"><i class="fa fa-arrow-circle-up"></i></button>' +
'<button ng-click="doRemove()" ng-show="canDownload() && !isReadonly()" class="btn" type="button"><i class="fa fa-times"></i></button>' +
'</div> ' +
'<a ng-show="text" href="javascript:" ng-click="doSave()">{{text}}</a>' +
'</div>'
});
})();