From abacdd97766d58312917901599c277f62bfbef3a Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Thu, 18 May 2017 10:41:00 +0200 Subject: [PATCH] [FIX] web: FieldRadio with numerical keys encoded as strings Before this rev., the FieldRadio didn't work on selection fields with keys like "0", "1"... i.e. strings that can be converted to numerical values. This was due to an automatic conversion of those keys to their numerical value by JQuery, so when the user changed the value, an unknow key was sent to the server (e.g. 1 instead of "1"), causing a crash. This rev. changes the logic a bit so that the keys are no more written in the DOM, but their index in the selection are. --- .../static/src/js/fields/relational_fields.js | 23 +++++---- addons/web/static/src/xml/base.xml | 3 +- .../tests/fields/relational_fields_tests.js | 50 ++++++++++++++++++- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 7f8cbd2eb45..a7b8559a4f2 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -1785,14 +1785,17 @@ var FieldRadio = FieldSelection.extend({ * @override */ _renderEdit: function () { - this.$("input").prop("checked", false); - var key; + var value; if (this.field.type === 'many2one') { - key = this.value && this.value.data.id; + value = this.value && this.value.data.id; } else { - key = this.value; + value = this.value; } - this.$('input[data-value="' + key + '"]').prop('checked', true); + var index = _.findIndex(this.values, function (option) { + return option[0] === value; + }); + this.$("input").prop("checked", false); + this.$('input[data-index="' + index + '"]').prop('checked', true); }, //-------------------------------------------------------------------------- @@ -1804,14 +1807,12 @@ var FieldRadio = FieldSelection.extend({ * @param {MouseEvent} event */ _onInputClick: function (event) { - var res_id = $(event.target).data('value'); + var index = $(event.target).data('index'); + var value = this.values[index]; if (this.field.type === 'many2one') { - var value = _.find(this.values, function (val) { - return val[0] === res_id; - }); - this._setValue({id: res_id, display_name: value[1]}); + this._setValue({id: value[0], display_name: value[1]}); } else { - this._setValue(res_id); + this._setValue(value[0]); } }, }); diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index b9b7caeea7d..ac463d12be1 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -729,7 +729,8 @@
- +
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index a6abf4be4b3..70dc16c6a40 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -4401,7 +4401,6 @@ QUnit.module('relational_fields', { form.destroy(); }); - QUnit.test('fieldradio widget on a selection in a new record', function (assert) { assert.expect(4); @@ -4429,6 +4428,55 @@ QUnit.module('relational_fields', { form.destroy(); }); + QUnit.test('fieldradio widget with numerical keys encoded as strings', function (assert) { + assert.expect(5); + + this.data.partner.fields.selection = { + type: 'selection', + selection: [['0', "Red"], ['1', "Black"]], + }; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '', + res_id: 1, + mockRPC: function (route, args) { + if (args.method === 'write') { + assert.strictEqual(args.args[1].selection, '1', + "should write correct value"); + } + return this._super.apply(this, arguments); + }, + }); + + + assert.strictEqual(form.$('.o_field_widget').text(), '', + "field should be unset"); + + form.$buttons.find('.o_form_button_edit').click(); + + assert.strictEqual(form.$('.o_radio_input:checked').length, 0, + "no value should be checked"); + + form.$("input.o_radio_input:nth(1)").click(); // click on 2nd option + + form.$buttons.find('.o_form_button_save').click(); + + assert.strictEqual(form.$('.o_field_widget').text(), 'Black', + "value should be 'Black'"); + + form.$buttons.find('.o_form_button_edit').click(); + + assert.strictEqual(form.$('.o_radio_input[data-index=1]:checked').length, 1, + "'Black' should be checked"); + + form.destroy(); + }); + QUnit.module('FieldMany2ManyCheckBoxes'); QUnit.test('widget many2many_checkboxes', function (assert) {