[FIX] web: FieldMonetary: don't loose focus after edition

... in x2many editable list views.

Field widgets can detect that they are at the origin of a
field_changed event, so that they don't re-render themselves when
they are being edited.

This didn't work for fields inside x2many list views. This wasn't
a big problem for most of the fields, because the cursor position
was automatically reset after a re-rendering, but it wasn't
working for monetary fields that empty their $el before each
re-rendering.

This rev. fixes the issue by making the field widgets inside
x2many list able to detect that they are the origin of a change,
and thus removes the now useless code that restore the cursor
position.
This commit is contained in:
Aaron Bohy
2017-05-08 08:10:00 +02:00
parent c75680c527
commit c04b840a45
3 changed files with 71 additions and 8 deletions
@@ -229,12 +229,7 @@ var InputField = DebouncedField.extend({
type: 'text',
placeholder: this.attrs.placeholder || "",
});
// Save cursor position to restore it after updating value
var selectionStart = this.$input[0].selectionStart;
var selectionEnd = this.$input[0].selectionEnd;
this.$input.val(this._formatValue(this.value));
this.$input[0].selectionStart = selectionStart;
this.$input[0].selectionEnd = selectionEnd;
return this.$input;
},
/**
@@ -600,7 +600,7 @@ var FieldX2Many = AbstractField.extend({
if (command.operation === 'UPDATE') {
var state = record.data[this.name];
var fieldNames = state.getFieldNames();
this.renderer.confirmChange(state, command.id, fieldNames);
this.renderer.confirmChange(state, command.id, fieldNames, ev.initialEvent);
return $.when();
}
}
@@ -787,12 +787,19 @@ var FieldX2Many = AbstractField.extend({
*/
_onFieldChanged: function (ev) {
if (ev.target === this) {
ev.initialEvent = this.lastInitialEvent;
return;
}
ev.stopPropagation();
// changes occured in an editable list
var changes = ev.data.changes;
// save the initial event triggering the field_changed, as it will be
// necessary when the field triggering this event will be reset (to
// prevent it from re-rendering itself, formatting its value, loosing
// the focus... while still being edited)
this.lastInitialEvent = undefined;
if (Object.keys(changes).length) {
this.lastInitialEvent = ev;
this._setValue({
operation: 'UPDATE',
id: ev.data.dataPointID,
@@ -1144,9 +1144,9 @@ QUnit.module('basic_fields', {
var evt = document.createEvent("MouseEvents"); //taken ref from https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
evt.initMouseEvent("mouseover", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
$('.discreteBar')[0].dispatchEvent(evt)
$('.discreteBar')[0].dispatchEvent(evt);
var tooltip = $('.nvtooltip').find('table').find('.key')[0].innerText;
assert.equal(tooltip,graph_key, "graph tooltip should be generated ")
assert.equal(tooltip,graph_key, "graph tooltip should be generated ");
$('.nvtooltip').remove();
// force a re-rendering of the first record (to check if the
@@ -1736,6 +1736,67 @@ QUnit.module('basic_fields', {
form.destroy();
});
QUnit.test('should keep the focus when being edited in x2many lists', function (assert) {
assert.expect(6);
this.data.partner.fields.currency_id.default = 1;
this.data.partner.fields.m2m = {
string: "m2m", type: "many2many", relation: 'partner', default: [[6, false, [2]]],
};
var form = createView({
View: FormView,
model: 'partner',
data: this.data,
arch:'<form string="Partners">' +
'<sheet>' +
'<field name="p"/>' +
'<field name="m2m"/>' +
'</sheet>' +
'</form>',
archs: {
'partner,false,list': '<tree editable="bottom">' +
'<field name="qux" widget="monetary"/>' +
'<field name="currency_id" invisible="1"/>' +
'</tree>',
},
session: {
currencies: _.indexBy(this.data.currency.records, 'id'),
},
});
// test the monetary field inside the one2many
var $o2m = form.$('.o_field_widget[name=p]');
$o2m.find('.o_field_x2many_list_row_add a').click();
$o2m.find('.o_field_widget input').val("22").trigger('input');
assert.strictEqual($o2m.find('.o_field_widget input').get(0), document.activeElement,
"the focus should still be on the input");
assert.strictEqual($o2m.find('.o_field_widget input').val(), "22",
"the value should not have been formatted yet");
form.$el.click(); // focusout the input
assert.strictEqual($o2m.find('.o_field_widget[name=qux]').html(), "$&nbsp;22.00",
"the value should have been formatted after losing the focus");
// test the monetary field inside the many2many
var $m2m = form.$('.o_field_widget[name=m2m]');
$m2m.find('.o_data_row td:first').click();
$m2m.find('.o_field_widget input').val("22").trigger('input');
assert.strictEqual($m2m.find('.o_field_widget input').get(0), document.activeElement,
"the focus should still be on the input");
assert.strictEqual($m2m.find('.o_field_widget input').val(), "22",
"the value should not have been formatted yet");
form.$el.click(); // focusout the input
assert.strictEqual($m2m.find('.o_field_widget[name=qux]').html(), "22.00&nbsp;€",
"the value should have been formatted after losing the focus");
form.destroy();
});
QUnit.module('FieldInteger');
QUnit.test('integer field when unset', function (assert) {