diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index be474ace3ef..2f0228c8cbd 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -1255,7 +1255,26 @@ var FieldFloatTime = FieldFloat.extend({ init: function () { this._super.apply(this, arguments); this.formatType = 'float_time'; - } + }, + /** + * Ensure the widget is re-rendered after being edited s.t. the value is + * directly formatted (without waiting for the record to be saved, as we do + * by default). + * + * See InputField@reset: we skip the call to _render if this widget initiated + * the change. + * + * Note: the default behavior could be changed s.t. all fields are formatted + * directly on blur. + * + * @override + */ + async reset() { + await this._super(...arguments); + if (!this.isDirty) { + await this._render(); + } + }, }); var FieldFloatFactor = FieldFloat.extend({ diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index eb6af34e037..bd29a96867f 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -522,14 +522,11 @@ QUnit.module('basic_fields', { QUnit.module('FieldNumeric'); QUnit.test('numeric field: fields with keydown on numpad decimal key', async function (assert) { - assert.expect(6); + assert.expect(5); this.data.partner.fields.float_factor_field = { string: "Float Factor", type: 'float_factor' }; this.data.partner.records[0].float_factor_field = 9.99; - this.data.partner.fields.float_time_field = { string: "Float Time", type: 'float_time' }; - this.data.partner.records[0].float_time_field = 9.99; - this.data.partner.fields.monetary = { string: "Monetary", type: 'monetary' }; this.data.partner.records[0].monetary = 9.99; this.data.partner.records[0].currency_id = 1; @@ -545,7 +542,6 @@ QUnit.module('basic_fields', {
- @@ -564,7 +560,6 @@ QUnit.module('basic_fields', { // Get all inputs const floatFactorField = form.el.querySelector('.o_input[name="float_factor_field"]'); const floatInput = form.el.querySelector('.o_input[name="qux"]'); - const floatTimeInput = form.el.querySelector('.o_input[name="float_time_field"]'); const integerInput = form.el.querySelector('.o_input[name="int_field"]'); const monetaryInput = form.el.querySelector('.o_input[name="monetary"]'); const percentageInput = form.el.querySelector('.o_input[name="percentage"]'); @@ -581,11 +576,6 @@ QUnit.module('basic_fields', { await testUtils.nextTick(); assert.ok(floatInput.value.endsWith('🇧🇪🇧🇪')); - floatTimeInput.dispatchEvent(new KeyboardEvent('keydown', { code: 'NumpadDecimal', key: '.' })); - floatTimeInput.dispatchEvent(new KeyboardEvent('keydown', { code: 'NumpadDecimal', key: ',' })); - await testUtils.nextTick(); - assert.ok(floatTimeInput.value.endsWith('🇧🇪🇧🇪')); - integerInput.dispatchEvent(new KeyboardEvent('keydown', { code: 'NumpadDecimal', key: '.' })); integerInput.dispatchEvent(new KeyboardEvent('keydown', { code: 'NumpadDecimal', key: ',' })); await testUtils.nextTick(); @@ -5780,6 +5770,74 @@ QUnit.module('basic_fields', { form.destroy(); }); + QUnit.test('float_time field value formatted on blur', async function (assert) { + assert.expect(4); + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: + ` + + `, + mockRPC: function (route, args) { + if (route === '/web/dataset/call_kw/partner/write') { + assert.strictEqual(args.args[1].qux, 9.5, 'the correct float value should be saved'); + } + return this._super.apply(this, arguments); + }, + res_id: 5, + }); + + assert.strictEqual(form.$('.o_field_widget').first().text(), '09:06', + 'The formatted time value should be displayed properly.'); + + await testUtils.form.clickEdit(form); + await testUtils.fields.editAndTrigger(form.$('input[name=qux]'), '9.5', ['change']); + assert.strictEqual(form.$('input[name=qux]').val(), '09:30', + 'The new value should be displayed properly in the input.'); + + await testUtils.form.clickSave(form); + assert.strictEqual(form.$('.o_field_widget').first().text(), '09:30', + 'The new value should be saved and displayed properly.'); + + form.destroy(); + }); + + QUnit.test('float_time field with invalid value', async function (assert) { + assert.expect(5); + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: + `
+ + `, + interceptsPropagate: { + call_service: function (ev) { + if (ev.data.service === 'notification') { + assert.strictEqual(ev.data.method, 'notify'); + assert.strictEqual(ev.data.args[0].title, 'Invalid fields:'); + assert.strictEqual(ev.data.args[0].message, '
  • Qux
'); + } + } + }, + }); + + await testUtils.fields.editAndTrigger(form.$('input[name=qux]'), 'blabla', ['change']); + await testUtils.form.clickSave(form); + assert.hasClass(form.$('input[name=qux]'), 'o_field_invalid'); + + await testUtils.fields.editAndTrigger(form.$('input[name=qux]'), '6.5', ['change']); + assert.doesNotHaveClass(form.$('input[name=qux]'), 'o_field_invalid', + "date field should not be displayed as invalid now"); + + form.destroy(); + }); + QUnit.module('FieldFloatFactor');