[IMP] base: Add option on image widget to enable zoom

Purpose
=======

As the employee picture on a form view is often too small,
it should be possible to zoom on it like for products in eCommerce.

Specification
=============

Added new bool options on FieldBinaryImage: `zoom` and `background`.

`zoom` will call zoomOdoo.js and display a popup with the zoomed out
image.

`background` is used to either display the image as a div element with
a background-url (to be used e.g. in a kanban view) or as a standard
img element.

closes odoo/odoo#33839

Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
Kevin Baptiste
2019-06-26 06:56:17 +00:00
committed by Yannick Tivisse
parent 2f34aea528
commit 83aaea9e5c
14 changed files with 149 additions and 35 deletions
@@ -22,6 +22,8 @@ var utils = require('web.utils');
var view_dialogs = require('web.view_dialogs');
var field_utils = require('web.field_utils');
require("web.zoomodoo");
var qweb = core.qweb;
var _t = core._t;
var _lt = core._lt;
@@ -1571,6 +1573,25 @@ var FieldBinaryImage = AbstractFieldBinary.extend({
'i': 'png',
'P': 'svg+xml',
},
/**
* Returns the image URL from a model.
*
* @private
* @param {string} model model from which to retrieve the image
* @param {string} res_id id of the record
* @param {string} field name of the image field
* @param {string} unique an unique integer for the record, usually __last_update
* @returns {string} URL of the image
*/
_getImageUrl: function (model, res_id, field, unique) {
return session.url('/web/image', {
model: model,
id: JSON.stringify(res_id),
field: field,
// unique forces a reload of the image when the record has been updated
unique: field_utils.format.datetime(unique).replace(/[^0-9]/g, ''),
});
},
_render: function () {
var self = this;
var url = this.placeholder;
@@ -1579,13 +1600,9 @@ var FieldBinaryImage = AbstractFieldBinary.extend({
// Use magic-word technique for detecting image type
url = 'data:image/' + (this.file_type_magic_word[this.value[0]] || 'png') + ';base64,' + this.value;
} else {
url = session.url('/web/image', {
model: this.model,
id: JSON.stringify(this.res_id),
field: this.nodeOptions.preview_image || this.name,
// unique forces a reload of the image when the record has been updated
unique: field_utils.format.datetime(this.recordData.__last_update).replace(/[^0-9]/g, ''),
});
var field = this.nodeOptions.preview_image || this.name;
var unique = this.recordData.__last_update;
url = this._getImageUrl(this.model, this.res_id, field, unique);
}
}
var $img = $(qweb.render("FieldBinaryImage-img", {widget: this, url: url}));
@@ -1608,6 +1625,62 @@ var FieldBinaryImage = AbstractFieldBinary.extend({
$img.attr('src', self.placeholder);
self.do_warn(_t("Image"), _t("Could not display the selected image."));
});
return this._super.apply(this, arguments);
},
/**
* Only enable the zoom on image in read-only mode, and if the option is enabled.
*
* @override
* @private
*/
_renderReadonly: function () {
this._super.apply(this, arguments);
if(this.nodeOptions.zoom) {
var unique = this.recordData.__last_update;
var url = this._getImageUrl(this.model, this.res_id, 'image', unique);
var $img;
if(this.nodeOptions.background)
{
if('tag' in this.nodeOptions) {
this.tagName = this.nodeOptions.tag;
}
if('class' in this.attrs) {
this.$el.addClass(this.attrs.class);
}
var urlThumb = this._getImageUrl(this.model, this.res_id, 'image_medium', unique);
this.$el.empty();
$img = this.$el;
$img.css('backgroundImage', 'url(' + urlThumb + ')');
} else {
$img = this.$('img');
}
if(this.recordData.image) {
$img.attr('data-zoom', 1);
$img.attr('data-zoom-image', url);
$img.zoomOdoo({
event: 'mouseenter',
attach: '.o_content',
attachToTarget: true,
onShow: function () {
if(this.$zoom.height() < 256 && this.$zoom.width() < 256) {
this.hide();
}
},
beforeAttach: function () {
this.$flyout.css({ width: '512px', height: '512px' });
},
preventClicks: this.nodeOptions.preventClicks,
});
}
}
},
});