[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.
This commit is contained in:
Aaron Bohy
2017-05-18 13:55:46 +02:00
parent 787daee41f
commit abacdd9776
3 changed files with 63 additions and 13 deletions
@@ -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]);
}
},
});
+2 -1
View File
@@ -729,7 +729,8 @@
<div t-if="widget.mode !== 'readonly'" t-attf-class="o_field_radio #{widget.nodeOptions.horizontal ? 'o_horizontal' : 'o_vertical'}">
<div t-foreach="widget.values" t-as="value" class="o_radio_item">
<input type="radio" class="o_radio_input" t-att-id="widget.unique_id + '_' + value[0]" t-att-name="widget.unique_id" t-att-data-value="value[0]"/>
<input type="radio" class="o_radio_input" t-att-id="widget.unique_id + '_' + value[0]"
t-att-name="widget.unique_id" t-att-data-value="value[0]" t-att-data-index="value_index"/>
<label t-if="!widget.nodeOptions.no_radiolabel" class="o_form_label" t-att-for="widget.unique_id + '_' + value[0]"><t t-esc="value[1]"/></label>
</div>
</div>
@@ -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: '<form>' +
'<field name="selection" widget="radio"/>' +
'</form>',
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) {