[FIX] web: prevent loss of edits in list view

Before this commit, it was possible to edit something in an editable
list view, then press the DOWN key, then enter some other values.  With
the DOWN key, the focus is supposed to move to the line below, so we
save the current line, in the current state.  This means that the edit
coming after are simply lost (well, just not saved nor displayed).

What this commit does is simply disable all control elements in that
situation.  This prevents uncomfortable situations from occurring.
This commit is contained in:
Géry Debongnie
2017-05-03 15:20:16 +02:00
parent c8dfc701bc
commit b38137d498
2 changed files with 40 additions and 1 deletions
@@ -425,6 +425,10 @@ ListRenderer.include({
* in edit mode. This is the moment we save all accumulated changes on that
* row, if needed (@see BasicController.saveRecord).
*
* Note that we have to disable the focusable elements (inputs, ...) to
* prevent subsequent editions. These edits would be lost, because the list
* view only saves records when unselecting a row.
*
* @returns {Deferred} The deferred resolves if the row was unselected (and
* possibly removed). If may be rejected, when the row is dirty and the
* user refuses to discard its changes.
@@ -436,13 +440,23 @@ ListRenderer.include({
}
var record = this.state.data[this.currentRow];
var recordWidgets = this.allFieldWidgets[record.id];
toggleWidgets(true);
var def = $.Deferred();
this.trigger_up('save_line', {
recordID: record.id,
onSuccess: def.resolve.bind(def),
onFailure: def.reject.bind(def),
});
return def;
return def.fail(toggleWidgets.bind(null, false));
function toggleWidgets(disabled) {
_.each(recordWidgets, function (widget) {
var $el = widget.getFocusableElement();
$el.prop('disabled', disabled);
});
}
},
//--------------------------------------------------------------------------
@@ -1759,6 +1759,31 @@ QUnit.module('Views', {
list.destroy();
});
QUnit.test('inputs are disabled when unselecting rows', function (assert) {
assert.expect(1);
var list = createView({
View: ListView,
model: 'foo',
data: this.data,
arch: '<tree editable="bottom"><field name="foo"/></tree>',
mockRPC: function (route, args) {
if (args.method === 'write') {
assert.strictEqual($input.prop('disabled'), true,
"input should be disabled");
}
return this._super.apply(this, arguments);
},
});
list.$('td:contains(gnap)').click();
var $input = list.$('tr.o_selected_row input[name="foo"]');
$input.val('lemon').trigger('input');
$input.trigger({type: 'keydown', which: $.ui.keyCode.DOWN});
list.destroy();
});
});
});