diff --git a/addons/web/static/src/legacy/js/fields/relational_fields.js b/addons/web/static/src/legacy/js/fields/relational_fields.js index d02f46e17ad..0b4c11ee302 100644 --- a/addons/web/static/src/legacy/js/fields/relational_fields.js +++ b/addons/web/static/src/legacy/js/fields/relational_fields.js @@ -3427,6 +3427,34 @@ var FieldRadio = FieldSelection.extend({ // Private //-------------------------------------------------------------------------- + /** + * @private + * @param {MouseEvent} ev + * @returns {Object} + */ + _getQuickEditExtraInfo: function (ev) { + // can be either the input or the label + const $target = ev.target.nodeName === 'INPUT' + ? $(ev.target) + : $(ev.target).siblings('input'); + + const index = $target.data('index'); + const value = this.values[index]; + return {value}; + }, + + /** + * @private + * @override + * @params {Object} extraInfo + */ + _quickEdit: function (extraInfo) { + if (extraInfo.value) { + this._saveValue(extraInfo.value); + } + return this._super.apply(this, arguments); + }, + /** * @private * @override @@ -3477,6 +3505,19 @@ var FieldRadio = FieldSelection.extend({ } }, + /** + * @private + * @param {Array} new value, [value] for a selection field, + * [id, display_name] for a Many2One + */ + _saveValue: function (value) { + if (this.field.type === 'many2one') { + this._setValue({id: value[0], display_name: value[1]}); + } else { + this._setValue(value[0]); + } + }, + //-------------------------------------------------------------------------- // Handlers //-------------------------------------------------------------------------- @@ -3486,12 +3527,12 @@ var FieldRadio = FieldSelection.extend({ * @param {MouseEvent} event */ _onInputClick: function (event) { - var index = $(event.target).data('index'); - var value = this.values[index]; - if (this.field.type === 'many2one') { - this._setValue({id: value[0], display_name: value[1]}); + if (this.mode === 'readonly') { + this._onClick(...arguments); } else { - this._setValue(value[0]); + const index = $(event.currentTarget).data('index'); + const value = this.values[index]; + this._saveValue(value); } }, }); diff --git a/addons/web/static/tests/legacy/views/form_tests.js b/addons/web/static/tests/legacy/views/form_tests.js index a400a034ac4..b3706eba4d9 100644 --- a/addons/web/static/tests/legacy/views/form_tests.js +++ b/addons/web/static/tests/legacy/views/form_tests.js @@ -11195,6 +11195,43 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('Quick Edition: Selection radio click on value', async function (assert) { + assert.expect(5); + + const form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: ` +
+ + + +
`, + res_id: 1, + mockRPC: function (route, args) { + if (args.model === 'partner' && args.method === 'write') { + assert.step('Write'); + } + return this._super(route, args); + }, + }); + + assert.containsOnce(form, '.o_form_view.o_form_readonly'); + assert.containsOnce(form, 'input[type="radio"]:eq(0):checked'); + + // click on the last value + await testUtils.dom.click(form.$('.o_radio_item .o_form_label:contains(EF)')); + + // should be switched in edit mode + assert.containsOnce(form, '.o_form_view.o_form_editable'); + assert.containsOnce(form, 'input[type="radio"]:eq(2):checked'); + + assert.verifySteps([], "No write RPC done"); + + form.destroy(); + }); + QUnit.test('Quick Edition: non-editable form', async function (assert) { assert.expect(3);