diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js index 0cb7742ffa17efb98badaaf1c3fbd37f9f598f07..3c818089d3220637d6fa1efae626aa7eb5df5114 100644 --- a/addons/web/static/src/js/fields/basic_fields.js +++ b/addons/web/static/src/js/fields/basic_fields.js @@ -91,6 +91,13 @@ var DebouncedField = AbstractField.extend({ init: function () { this._super.apply(this, arguments); + // isDirty is used to detect that the user interacted at least once with + // the widget, so that we can prevent it from triggering a field_changed + // in commitChanges if the user didn't change anything (this is required + // as sometimes it is hard to detect that an unset value is still unset, + // e.g. if a numerical field contains the value 0, is it because it is + // still unset or because the user set it to 0? + this.isDirty = false; if (this.DEBOUNCE && this.mode === 'edit') { this._doDebouncedAction = _.debounce(this._doDebouncedAction.bind(this), this.DEBOUNCE); } @@ -108,7 +115,7 @@ var DebouncedField = AbstractField.extend({ * @override */ commitChanges: function () { - if (this.mode === 'edit') { + if (this.isDirty && this.mode === 'edit') { this._setValue(this._getValue()); } }, @@ -158,6 +165,7 @@ var DebouncedField = AbstractField.extend({ * @private */ _onInput: function () { + this.isDirty = true; this._doDebouncedAction(); }, }); diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index a24944ed8a11618ee8e41be5279d5e8e39875eec..c1fb007b937e770db8a889bba7946f7f07f30e2a 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -438,6 +438,35 @@ QUnit.module('basic_fields', { list.destroy(); }); + QUnit.test('do not trigger a field_changed if they have not changed', function (assert) { + assert.expect(2); + + this.data.partner.records[1].qux = undefined; + this.data.partner.records[1].int_field = undefined; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'<form string="Partners">' + + '<sheet>' + + '<field name="qux" widget="float" digits="[5,3]"/>' + + '<field name="int_field"/>' + + '</sheet>' + + '</form>', + res_id: 2, + mockRPC: function (route, args) { + assert.step(args.method); + return this._super.apply(this, arguments); + } + }); + + form.$buttons.find('.o_form_button_edit').click(); + form.$buttons.find('.o_form_button_save').click(); + + assert.verifySteps(['read']); // should not have save as nothing changed + + form.destroy(); + }); QUnit.module('FieldEmail');