diff options
| author | Michael Mattiello (mcm) <mcm@odoo.com> | 2020-01-27 07:17:49 +0000 |
|---|---|---|
| committer | Michael Mattiello (mcm) <mcm@odoo.com> | 2020-02-06 11:55:13 +0000 |
| commit | c5e34d77f5d84c1811e29cabdffdd408695d1d2d (patch) | |
| tree | f083b7a8f74fe322be91a2bfcdbb40d8aab5ad35 /addons/web | |
| parent | 9d85bce7db59ebf8cb65c2aa13524fdc69944eb2 (diff) | |
[IMP] web: show % symbol outside the input in percentage widget
Before this commit the % symbol was part of the input. We could write a
value with the % symbol to divide the value by 100 (50% = 0.5, 50 = 50)
This commit removes the % symbol from the input and adds it in a span
after the input so we do not need to write the % symbol anymore.
The value from the input will be saved as $value / 100 in database.
task-2065078
closes odoo/odoo#43995
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Diffstat (limited to 'addons/web')
| -rw-r--r-- | addons/web/static/src/js/fields/basic_fields.js | 35 | ||||
| -rw-r--r-- | addons/web/static/src/js/fields/field_utils.js | 17 | ||||
| -rw-r--r-- | addons/web/static/src/scss/fields.scss | 4 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/basic_fields_tests.js | 40 | ||||
| -rw-r--r-- | addons/web/static/tests/fields/field_utils_tests.js | 17 |
5 files changed, 91 insertions, 22 deletions
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index f2c44891ea2..4aac42db13b 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1325,8 +1325,41 @@ var FieldFloatToggle = AbstractField.extend({ }); var FieldPercentage = FieldFloat.extend({ + className: 'o_field_float_percentage o_field_number', description: _lt("Percentage"), - formatType:'percentage', + + /** + * @constructor + */ + init() { + this._super(...arguments); + if (this.mode === 'edit') { + this.tagName = 'div'; + this.className += ' o_input'; + + // do not display % in the input in edit + this.formatOptions.noSymbol = true; + } + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * For percentage widget, the input is inside a div, alongside a span + * containing the percentage(%) symbol. + * + * @override + * @private + */ + _renderEdit() { + this.$el.empty(); + // Prepare and add the input + this._prepareInput(this.$input).appendTo(this.$el); + const $percentageSymbol = $('<span>', { text: '%' }); + this.$el.append($percentageSymbol); + }, }); var FieldText = InputField.extend(TranslatableFieldMixin, { diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js index f8546f90e55..8bba006aaf1 100644 --- a/addons/web/static/src/js/fields/field_utils.js +++ b/addons/web/static/src/js/fields/field_utils.js @@ -370,11 +370,11 @@ function formatMonetary(value, field, options) { */ function formatPercentage(value, field, options) { options = options || {}; - var result = formatFloat(value * 100, field, options) || '0'; - if (options.humanReadable && options.humanReadable(value * 100)) { - return result + "%"; + let result = formatFloat(value * 100, field, options) || '0'; + if (!options.humanReadable || !options.humanReadable(value * 100)) { + result = parseFloat(result).toString().replace('.', _t.database.parameters.decimal_point); } - return (parseFloat(result) + "%").replace('.', _t.database.parameters.decimal_point); + return result + (options.noSymbol ? '' : '%'); } /** * Returns a string representing the value of the selection. @@ -598,8 +598,8 @@ function parseFloatTime(value) { } /** - * Parse a String containing a percentage and convert it to float. - * The percentage can be a regular xx.xx float or a xx%. + * Parse a String containing float and unconvert it with a conversion factor + * of 100. The percentage can be a regular xx.xx float or a xx%. * * @param {string} value * The string to be parsed @@ -607,10 +607,7 @@ function parseFloatTime(value) { * @throws {Error} if the value couldn't be converted to float */ function parsePercentage(value) { - if (value.slice(-1) === '%') { - return parseFloat(value.slice(0, -1)) / 100; - } - return parseFloat(value); + return parseFloat(value) / 100; } /** diff --git a/addons/web/static/src/scss/fields.scss b/addons/web/static/src/scss/fields.scss index 05862d3746f..6bae4914db1 100644 --- a/addons/web/static/src/scss/fields.scss +++ b/addons/web/static/src/scss/fields.scss @@ -38,7 +38,7 @@ } // Flex fields (inline) - &.o_field_many2one, &.o_field_radio, &.o_field_many2manytags, &.o_field_percent_pie, &.o_field_monetary, &.o_field_binary_file { + &.o_field_many2one, &.o_field_radio, &.o_field_many2manytags, &.o_field_percent_pie, &.o_field_monetary, &.o_field_binary_file, &.o_field_float_percentage { display: inline-flex; > span, > button { flex: 0 0 auto; @@ -72,7 +72,7 @@ } // Monetary - &.o_field_monetary { + &.o_field_monetary, &.o_field_float_percentage { &.o_input { align-items: baseline; diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index 1cd7b35b6be..cb19958ef94 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -904,6 +904,46 @@ QUnit.module('basic_fields', { form.destroy(); }); + QUnit.module('Percentage'); + + QUnit.test('percentage widget in form view', async function (assert) { + assert.expect(6); + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: ` <form string="Partners"> + <field name="qux" widget="percentage"/> + </form>`, + mockRPC: function (route, args) { + if (args.method === 'write') { + assert.strictEqual(args.args[1].qux, 0.24, 'the correct float value should be saved'); + } + return this._super(...arguments); + }, + res_id: 1, + }); + + assert.strictEqual(form.$('.o_field_widget').first().text(), '44.4%', + 'The value should be displayed properly.'); + + await testUtils.form.clickEdit(form); + assert.strictEqual(form.$('.o_field_widget[name=qux] input').val(), '44.4', + 'The input should be rendered without the percentage symbol.'); + assert.strictEqual(form.$('.o_field_widget[name=qux] span').text(), '%', + 'The input should be followed by a span containing the percentage symbol.'); + + await testUtils.fields.editInput(form.$('.o_field_float_percentage input'), '24'); + assert.strictEqual(form.$('.o_field_widget[name=qux] input').val(), '24', + 'The value should not be formated yet.'); + + await testUtils.form.clickSave(form); + assert.strictEqual(form.$('.o_field_widget').text(), '24%', + 'The new value should be formatted properly.'); + + form.destroy(); + }); QUnit.module('FieldEmail'); diff --git a/addons/web/static/tests/fields/field_utils_tests.js b/addons/web/static/tests/fields/field_utils_tests.js index e0b9564d13c..1437b6b0506 100644 --- a/addons/web/static/tests/fields/field_utils_tests.js +++ b/addons/web/static/tests/fields/field_utils_tests.js @@ -135,7 +135,7 @@ QUnit.test('format binary', function (assert) { }); QUnit.test('format percentage', function (assert) { - assert.expect(11); + assert.expect(12); var originalParameters = _.clone(core._t.database.parameters); @@ -161,6 +161,7 @@ QUnit.test('format percentage', function (assert) { }); assert.strictEqual(fieldUtils.format.percentage(0.125), '12,5%'); assert.strictEqual(fieldUtils.format.percentage(0.666666), '66,67%'); + assert.strictEqual(fieldUtils.format.percentage(0.5, null, { noSymbol: true }), '50'); core._t.database.parameters = originalParameters; }); @@ -274,17 +275,15 @@ QUnit.test('parse monetary', function(assert) { }); QUnit.test('parse percentage', function(assert) { - assert.expect(9); + assert.expect(7); var originalParameters = _.clone(core._t.database.parameters); assert.strictEqual(fieldUtils.parse.percentage(""), 0); assert.strictEqual(fieldUtils.parse.percentage("0"), 0); - assert.strictEqual(fieldUtils.parse.percentage("0%"), 0); - assert.strictEqual(fieldUtils.parse.percentage("0.02"), 0.02); - assert.strictEqual(fieldUtils.parse.percentage("1"), 1); - assert.strictEqual(fieldUtils.parse.percentage("2%"), 0.02); - assert.strictEqual(fieldUtils.parse.percentage("100%"), 1); + assert.strictEqual(fieldUtils.parse.percentage("0.5"), 0.005); + assert.strictEqual(fieldUtils.parse.percentage("1"), 0.01); + assert.strictEqual(fieldUtils.parse.percentage("100"), 1); _.extend(core._t.database.parameters, { grouping: [3, 0], @@ -292,8 +291,8 @@ QUnit.test('parse percentage', function(assert) { thousands_sep: '.' }); - assert.strictEqual(fieldUtils.parse.percentage("0,04"), 0.04); - assert.strictEqual(fieldUtils.parse.percentage("6,02%"), 0.0602); + assert.strictEqual(fieldUtils.parse.percentage("1.234,56"), 12.3456); + assert.strictEqual(fieldUtils.parse.percentage("6,02"), 0.0602); core._t.database.parameters = originalParameters; |
