diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index 08b9e7f1602..3cd93bb6e8b 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -13,6 +13,7 @@ odoo.define('web.EditableListRenderer', function (require) { */ var core = require('web.core'); var ListRenderer = require('web.ListRenderer'); +var utils = require('web.utils'); var _t = core._t; @@ -153,12 +154,32 @@ ListRenderer.include({ */ setRowMode: function (recordID, mode) { var self = this; - var rowIndex = _.findIndex(this.state.data, {id: recordID}); + + // find the record and its row index (handles ungrouped and grouped cases + // as even if the grouped list doesn't support edition, it may contain + // a widget allowing the edition in readonly (e.g. priority), so it + // should be able to update a record as well) + var record; + var rowIndex; + if (this.state.groupedBy.length) { + rowIndex = -1; + var count = 0; + utils.traverse_records(this.state, function (r) { + if (r.id === recordID) { + record = r; + rowIndex = count; + } + count++; + }); + } else { + rowIndex = _.findIndex(this.state.data, {id: recordID}); + record = this.state.data[rowIndex]; + } + if (rowIndex < 0) { return $.when(); } var editMode = (mode === 'edit'); - var record = this.state.data[rowIndex]; this.currentRow = editMode ? rowIndex : null; var $row = this.$('.o_data_row:nth(' + rowIndex + ')'); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index e3d8acfe84a..f0370ac7cf8 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -2483,6 +2483,34 @@ QUnit.module('Views', { list.destroy(); }); + + QUnit.test('grouped list edition with toggle_button widget', function (assert) { + assert.expect(3); + + var list = createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '', + groupBy: ['m2o'], + mockRPC: function (route, args) { + if (args.method === 'write') { + assert.deepEqual(args.args[1], {bar: false}, + "should write the correct value"); + } + return this._super.apply(this, arguments); + }, + }); + + list.$('.o_group_header:first').click(); // open the first group + assert.strictEqual(list.$('.o_data_row:first .o_toggle_button_success').length, 1, + "boolean value of the first record should be true"); + list.$('.o_data_row:first .o_icon_button').click(); // toggle the value + assert.strictEqual(list.$('.o_data_row:first .text-muted:not(.o_toggle_button_success)').length, 1, + "boolean button should have been updated"); + + list.destroy(); + }); }); });