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 445967287bf..7e702e30862 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -949,8 +949,8 @@ var BasicModel = AbstractModel.extend({ */ addFieldsInfo: function (recordID, viewInfo) { var record = this.localData[recordID]; - record.fields = _.defaults(record.fields, viewInfo.fields); - record.fieldsInfo = _.defaults(record.fieldsInfo, viewInfo.fieldsInfo); + record.fields = _.extend({}, record.fields, viewInfo.fields); + record.fieldsInfo = _.extend({}, record.fieldsInfo, viewInfo.fieldsInfo); }, /** * Manually sets a resource as dirty. This is used to notify that a field diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 8f789c88647..8a67f6eec05 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -135,6 +135,7 @@ QUnit.module('relational_fields', { partner_ids: [], turtle_ref: 'product,37', }], + onchanges: {}, }, user: { fields: { @@ -2677,6 +2678,45 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('edition of one2many field, with onchange and not inline sub view', function (assert) { + assert.expect(2); + + this.data.turtle.onchanges.turtle_int = function (obj) { + obj.turtle_foo = String(obj.turtle_int); + }; + this.data.partner.onchanges.turtles = function () {}; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '', + archs: { + 'turtle,false,list': '', + 'turtle,false,form': '
', + }, + mockRPC: function (route, args) { + return this._super.apply(this, arguments); + }, + res_id: 1, + }); + form.$buttons.find('.o_form_button_edit').click(); + form.$('.o_field_x2many_list_row_add a').click(); + $('input[name="turtle_int"]').val('5').trigger('input'); + $('.modal-footer button.btn-primary').first().click(); + assert.strictEqual(form.$('tbody tr:eq(1) td.o_data_cell').text(), '5', + 'should display 5 in the foo field'); + form.$('tbody tr:eq(1) td.o_data_cell').click(); + + $('input[name="turtle_int"]').val('3').trigger('input'); + $('.modal-footer button.btn-primary').first().click(); + assert.strictEqual(form.$('tbody tr:eq(1) td.o_data_cell').text(), '3', + 'should now display 3 in the foo field'); + form.destroy(); + }); + QUnit.test('sorting one2many fields', function (assert) { assert.expect(4); diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index 76391e4cb7a..f78de2f5c0b 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -32,9 +32,6 @@ var MockServer = Class.extend({ if (!('name' in model.fields)) { model.fields.name = {string: "Name", type: "char", default: "name"}; } - for (var fieldName in model.onchanges) { - model.fields[fieldName].onChange = "1"; - } model.records = model.records || []; for (var i = 0; i < model.records.length; i++) { @@ -282,7 +279,7 @@ var MockServer = Class.extend({ // add onchanges if (name in onchanges) { - field.onChange="1"; + node.attrs.on_change="1"; } }); return { diff --git a/addons/web/static/tests/views/basic_model_tests.js b/addons/web/static/tests/views/basic_model_tests.js index b2a00f1ca09..8de3e3c91a2 100644 --- a/addons/web/static/tests/views/basic_model_tests.js +++ b/addons/web/static/tests/views/basic_model_tests.js @@ -203,6 +203,7 @@ QUnit.module('Views', { QUnit.test('basic onchange', function (assert) { assert.expect(5); + this.data.partner.fields.foo.onChange = true; this.data.partner.onchanges.foo = function (obj) { obj.bar = obj.foo.length; }; @@ -240,6 +241,7 @@ QUnit.module('Views', { QUnit.test('onchange with a many2one', function (assert) { assert.expect(5); + this.data.partner.fields.product_id.onChange = true; this.data.partner.onchanges.product_id = function (obj) { if (obj.product_id === 37) { obj.foo = "space lollipop"; @@ -280,6 +282,7 @@ QUnit.module('Views', { QUnit.test('onchange on a one2many not in view (fieldNames)', function (assert) { assert.expect(6); + this.data.partner.fields.foo.onChange = true; this.data.partner.onchanges.foo = function (obj) { obj.bar = obj.foo.length; obj.product_ids = []; @@ -425,6 +428,7 @@ QUnit.module('Views', { QUnit.test('onchange on a char with an unchanged many2one', function (assert) { assert.expect(2); + this.data.partner.fields.foo.onChange = true; this.data.partner.onchanges.foo = function (obj) { obj.foo = obj.foo + " alligator"; }; @@ -453,6 +457,7 @@ QUnit.module('Views', { QUnit.test('onchange on a char with another many2one not set to a value', function (assert) { assert.expect(2); this.data.partner.records[0].product_id = false; + this.data.partner.fields.foo.onChange = true; this.data.partner.onchanges.foo = function (obj) { obj.foo = obj.foo + " alligator"; }; @@ -1153,6 +1158,7 @@ QUnit.module('Views', { assert.expect(4); this.data.partner.fields.total.default = 50; + this.data.partner.fields.product_ids.onChange = true; this.data.partner.onchanges.product_ids = function (obj) { obj.total += 100; }; @@ -1497,6 +1503,7 @@ QUnit.module('Views', { assert.expect(6); this.params.fieldNames = ['foo', 'bar']; + this.data.partner.fields.foo.onChange = true; this.data.partner.onchanges.foo = function (obj) { obj.bar = obj.foo.length; }; @@ -1561,6 +1568,7 @@ QUnit.module('Views', { assert.expect(6); this.params.fieldNames = ['foo', 'bar']; + this.data.partner.fields.foo.onChange = true; this.data.partner.onchanges.foo = function (obj) { obj.bar = obj.foo.length; };