[FIX] web: reimplement autosize for fun (and some bugfixing)

autosize does not work correctly (it moves the screen in all directions
sometimes when the user press enter in the bottom of the screen in some
browser),

So, we decided to have our own version, because of course, we can do it better.  A
few horrible hacks later, I proudly present you "autoresize" (it was
almost named "odooresize" but common sense prevailed).

As added benefits, it plays better with our web client, so when you open
a dialog in a modal for example, the autosize fields should have the
correct height automagically (or should I say 'odoomagically')
This commit is contained in:
Géry Debongnie
2016-01-11 14:32:51 +01:00
parent 7d30769980
commit 29427bdcb3
3 changed files with 65 additions and 10 deletions
@@ -441,3 +441,65 @@ return {
});
odoo.define('web.dom_utils', function (require) {
"use strict";
var core = require('web.core');
// TO DO: move this into new file dom_utils.js
/**
* Autoresize a $textarea node, by recomputing its height when necessary
* @param {number} [options.min_height] by default, 50.
* @param {Widget} [options.parent] if set, autoresize will listen to some extra
* events to decide when to resize itself. This is useful for widgets that are
* not in the dom when the autoresize is declared.
*/
function autoresize ($textarea, options) {
options = options || {};
var $fixed_text_area;
var min_height = (options && options.min_height) || 50;
if (!$fixed_text_area) {
$fixed_text_area = $('<textarea>').css({
position: 'absolute',
opacity: 0,
height: 10,
top: -10000,
left: -10000,
});
$fixed_text_area.addClass($fixed_text_area[0].classList);
$fixed_text_area.insertAfter($textarea);
}
resize();
if ($textarea.__auto_resized) {
return;
}
$textarea.__auto_resized = true;
$textarea.on('input focus', resize);
if (options.parent) {
core.bus.on('DOM_updated', options.parent, resize);
core.bus.on('view_shown', options.parent, resize);
}
function resize () {
var heightOffset;
var style = window.getComputedStyle($textarea[0], null);
if (style.boxSizing === 'content-box') {
heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom));
} else {
heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
}
$fixed_text_area.width($textarea.outerWidth());
$fixed_text_area.val($textarea.val());
var height = $fixed_text_area[0].scrollHeight;
$textarea.css({height: Math.max(height + heightOffset, min_height)});
}
}
return {
autoresize: autoresize,
};
});
@@ -15,6 +15,7 @@ var Priority = require('web.Priority');
var pyeval = require('web.pyeval');
var session = require('web.session');
var utils = require('web.utils');
var dom_utils = require('web.dom_utils');
var _t = core._t;
var QWeb = core.qweb;
@@ -573,16 +574,8 @@ var FieldText = common.AbstractField.extend(common.ReinitializeFieldMixin, {
render_value: function() {
if (! this.get("effective_readonly")) {
var show_value = formats.format_value(this.get('value'), this, '');
if (show_value === '') {
this.$textarea.css('height', parseInt(this.default_height, 10)+"px");
}
this.$textarea.val(show_value);
if (! this.auto_sized) {
this.auto_sized = true;
autosize(this.$textarea);
} else {
this.$textarea.trigger("autosize");
}
dom_utils.autoresize(this.$textarea, {parent: this, min_height: parseInt(this.default_height)});
} else {
var txt = this.get("value") || '';
this.$(".oe_form_text_content").text(txt);
+1 -1
View File
@@ -449,7 +449,7 @@ Tour.register({
},
{
title: "change text value",
element: '.oe_form_field[data-fieldname="body"] textarea',
element: '.oe_form_field[data-fieldname="body"] textarea[name="body"]',
sampleText: 'ccc'
},
{