diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 304f7e475f7..47d5cee5c9c 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -942,10 +942,16 @@ var BasicModel = AbstractModel.extend({ params.res_id = command[1]; } rec = self._makeDataPoint(params); - var data = command[2]; - _.each(Object.keys(data), function (name) { + var data = {}; + _.each(Object.keys(command[2]), function (name) { var field = rec.fields[name]; - if (field && field.type === 'many2one') { + if (!field) { + // ignore if this field is unknown as we don't + // know if it requires a special handling + return; + } + data[name] = command[2][name]; + if (field.type === 'many2one') { var r = self._makeDataPoint({ modelName: field.relation, data: { @@ -957,9 +963,6 @@ var BasicModel = AbstractModel.extend({ } }); rec._changes = data; - for (var f in rec._changes) { - rec.data[f] = null; - } list._changes.push(rec.id); } if (command[0] === 5) { diff --git a/addons/web/static/test/views/form_tests.js b/addons/web/static/test/views/form_tests.js index 06616a407d6..a202ba93995 100644 --- a/addons/web/static/test/views/form_tests.js +++ b/addons/web/static/test/views/form_tests.js @@ -2275,6 +2275,72 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('onchanges on unknown fields of o2m are ignored', function (assert) { + // many2one fields need to be postprocessed (the onchange returns [id, + // display_name]), but if we don't know the field, we can't know it's a + // many2one, so it isn't ignored, its value is an array instead of a + // dataPoint id, which may cause errors later (e.g. when saving). + assert.expect(2); + + this.data.partner.records[1].p = [4]; + this.data.partner.onchanges = { + foo: function () {}, + }; + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
' + + '', + res_id: 2, + mockRPC: function (route, args) { + if (args.method === 'onchange') { + return $.when({ + value: { + p: [ + [5], + [1, 4, { + foo: 'foo changed', + product_id: [37, "xphone"], + }] + ], + }, + }); + } + if (args.method === 'write') { + assert.deepEqual(args.args[1].p, [[1, 4, { + foo: 'foo changed', + }]], "should only write value of known fields"); + } + return this._super.apply(this, arguments); + }, + }); + + form.$buttons.find('.o_form_button_edit').click(); + form.$('.o_form_input:first').val('trigger an onchange').trigger('input'); + + assert.strictEqual(form.$('.o_data_row td:first').text(), 'foo changed', + "onchange should have been correctly applied on field in o2m list"); + + form.$buttons.find('.o_form_button_save').click(); + + form.destroy(); + }); + QUnit.test('navigation with tab key in form view', function (assert) { assert.expect(2);