[FIX] web: fix space symbol in monetary field's title in list view

Browsers don't render html entity in the "title" attribute and we cannot use
them. Otherwise we may get values like "$ 100".

Fix it by using special character and not html entity. It works both in html
strings and attributues

The problem was reported here:
https://github.com/odoo/odoo/pull/90191#issuecomment-1156034355

STEPS: open invoice and put pointer over monetary field in the list.

Note, that to reproduce the problem, the widget should not be specifed
explicitly. See
https://github.com/odoo/odoo/blob/5b9fada39913cd456a3659faef1160f84ae19860/addons/web/static/src/js/views/list/list_renderer.js#L436-L439
https://github.com/odoo/odoo/blob/5b9fada39913cd456a3659faef1160f84ae19860/addons/web/static/src/js/views/list/list_renderer.js#L452-L456

closes odoo/odoo#97323

X-original-commit: e4ff65b8d9b46dcddab100e5eb4901eaa94e7009
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Samuel Degueldre <sad@odoo.com>
Signed-off-by: Ivan Elizaryev (iel) <iel@odoo.com>
This commit is contained in:
Ivan Yelizariev
2022-08-02 15:49:54 +02:00
parent 20369e46e1
commit 7b56fc4c71
2 changed files with 64 additions and 4 deletions
@@ -23,6 +23,8 @@ var utils = require('web.utils');
var _t = core._t;
const NBSP = "\u00a0";
//------------------------------------------------------------------------------
// Formatting
//------------------------------------------------------------------------------
@@ -330,8 +332,12 @@ function formatX2Many(value) {
* digits precision in the field. Note: if the currency defines a
* precision, the currency's one is used.
* @param {boolean} [options.forceString=false]
* if false, returns a string encoding the html formatted value (with
* whitespace encoded as '&nbsp;')
* if true, returns a string with regular whitespace. Otherwise it uses
* non-breaking whitespace unicode character. The option is presented for
* historical reason and will be removed in master. Previous
* implementation used html entity `&nbsp;`, which doesn't work in html
* attributes. With new implementation we can always use the unicode
* character and the option is not needed anymore.
* @returns {string | _Markup}
*/
function formatMonetary(value, field, options) {
@@ -367,7 +373,7 @@ function formatMonetary(value, field, options) {
if (options.forceString) {
return val.join(' ');
}
return utils.Markup(val.map((v) => _.escape(v)).join('&nbsp;'));
return utils.Markup(val.map((v) => _.escape(v)).join(NBSP));
}
/**
* Returns a string representing the given value (multiplied by 100)
@@ -611,6 +617,9 @@ function parseFloat(value) {
*/
function parseMonetary(value, field, options) {
var values = value.split('&nbsp;');
if (values.length === 1) {
values = value.split(NBSP);
}
if (values.length === 1) {
return parseFloat(value);
}
@@ -58,6 +58,7 @@ QUnit.module('Legacy basic_fields', {
txt: {string: "txt", type: "text", default: "My little txt Value\nHo-ho-hoooo Merry Christmas"},
int_field: {string: "int_field", type: "integer", sortable: true, searchable: true},
qux: {string: "Qux", type: "float", digits: [16,1], searchable: true},
monetary: {string: "MMM", type: "monetary", digits: [16,1], searchable: true},
p: {string: "one2many field", type: "one2many", relation: 'partner', searchable: true},
trululu: {string: "Trululu", type: "many2one", relation: 'partner', searchable: true},
timmy: {string: "pokemon", type: "many2many", relation: 'partner_type', searchable: true},
@@ -107,7 +108,17 @@ QUnit.module('Legacy basic_fields', {
selection: 'done',
},
{id: 3, bar: true, foo: "gnap", int_field: 80, qux: -3.89859},
{id: 5, bar: false, foo: "blop", int_field: -4, qux: 9.1, currency_id: 1}],
{id: 5, bar: false, foo: "blop", int_field: -4, qux: 9.1, currency_id: 1, monetary: 99.9}],
onchanges: {},
},
team: {
fields: {
partner_ids: { string: "Partner", type: "one2many", relation: 'partner' },
},
records: [{
id: 1,
partner_ids: [5],
}],
onchanges: {},
},
product: {
@@ -5771,6 +5782,46 @@ QUnit.module('Legacy basic_fields', {
form.destroy();
});
QUnit.test('monetary field in the lines of a form view', async function (assert) {
assert.expect(4);
var form = await createView({
View: FormView,
model: 'team',
data: this.data,
arch:'<form>' +
'<sheet>' +
'<field name="partner_ids">' +
'<tree editable="bottom">' +
'<field name="monetary"/>' +
'<field name="currency_id" invisible="1"/>' +
'</tree>' +
'</field>' +
'</sheet>' +
'</form>',
res_id: 1,
session: {
currencies: _.indexBy(this.data.currency.records, 'id'),
},
});
// Non-breaking space between the currency and the amount
assert.strictEqual(form.$('.o_list_table .o_list_number').first().text(), '$\u00a099.9',
'The value should be displayed properly.');
assert.hasAttrValue(form.$('.o_list_table .o_list_number').first(), 'title', '$\u00a099.9',
'The title value should be displayed properly.');
await testUtils.form.clickEdit(form);
// Non-breaking space between the currency and the amount
assert.strictEqual(form.$('.o_list_table .o_list_number').first().text(), '$\u00a099.9',
'The value should be displayed properly.');
assert.hasAttrValue(form.$('.o_list_table .o_list_number').first(), 'title', '$\u00a099.9',
'The title value should be displayed properly.');
form.destroy();
});
QUnit.test('monetary field rounding using formula in form view', async function (assert) {
assert.expect(1);