[FIX] web: lists: focus last edited cell

Gave back focus to the last edited cell to increase usability with key nav.

Before this commit, after saving several records with multi edition in a list,
focus was lost (given to the body).

Now, last edited cell is given back the focus after multi editing.
This commit is contained in:
Julien Mougenot
2019-09-18 11:31:43 +00:00
committed by Aaron Bohy
parent 34e5271d7b
commit 4fba43c027
3 changed files with 29 additions and 6 deletions
@@ -477,6 +477,7 @@ var ListController = BasicController.extend({
this.model.discardChanges(recordId);
return this._confirmSave(recordId).then(reject);
};
let dialog;
if (validRecordIds.length > 0) {
let message;
if (nbInvalid === 0) {
@@ -488,13 +489,13 @@ var ListController = BasicController.extend({
_t("Do you want to set the value on the %d valid selected records? (%d invalid)"),
validRecordIds.length, nbInvalid);
}
Dialog.confirm(this, message, {
dialog = Dialog.confirm(this, message, {
confirm_callback: () => {
this.model.saveRecords(recordId, validRecordIds, fieldName)
.then(() => {
return this.model.saveRecords(recordId, validRecordIds, fieldName)
.then(async () => {
this._updateButtons('readonly');
const state = this.model.get(this.handle);
this.renderer.updateState(state, {keepWidths: true});
await this.renderer.updateState(state, {keepWidths: true});
resolve(Object.keys(changes));
})
.guardedCatch(rejectAndDiscard);
@@ -502,10 +503,17 @@ var ListController = BasicController.extend({
cancel_callback: rejectAndDiscard,
});
} else {
Dialog.alert(this, _t("No valid record to save"), {
dialog = Dialog.alert(this, _t("No valid record to save"), {
confirm_callback: rejectAndDiscard,
});
}
dialog.on('closed', this, async () => {
// we need to wait for the dialog to be actually closed, but
// the 'closed' event is triggered just before, and it prevents
// from focussing the cell
await Promise.resolve();
this.renderer.focusCell(recordId, node);
});
});
},
/**
@@ -319,6 +319,17 @@ ListRenderer.include({
var rowIndex = $row.prop('rowIndex') - 1;
this._selectCell(rowIndex, 0);
},
/**
* Gives focus to a specific cell, given its row and its related column.
*
* @param {string} recordId
* @param {Object} column
*/
focusCell: function (recordId, column) {
var $row = this._getRow(recordId);
var cellIndex = this.columns.indexOf(column);
$row.find('.o_data_cell')[cellIndex].focus();
},
/**
* Returns the recordID associated to the line which is currently in edition
* or null if there is no line in edition.
+5 -1
View File
@@ -5308,7 +5308,7 @@ QUnit.module('Views', {
});
QUnit.test('editable list view: multi edition', async function (assert) {
assert.expect(22);
assert.expect(24);
var list = await createView({
View: ListView,
@@ -5364,6 +5364,8 @@ QUnit.module('Views', {
await testUtils.dom.click($('.modal .btn:contains(Cancel)'));
assert.strictEqual(list.$('.o_data_row:eq(0) .o_data_cell').text(), 'yop10',
"changes have been discarded and row is back to readonly");
assert.strictEqual(document.activeElement, list.$('.o_data_row:eq(0) .o_data_cell:eq(1)')[0],
"focus should be given to the most recently edited cell after discard");
await testUtils.dom.click(list.$('.o_data_row:eq(0) .o_data_cell:eq(1)'));
await testUtils.fields.editInput(list.$('.o_field_widget[name=int_field]'), 666);
await testUtils.dom.click(list.$('.o_data_row:eq(1) .o_data_cell:eq(0)'));
@@ -5376,6 +5378,8 @@ QUnit.module('Views', {
assert.strictEqual(list.$('.o_data_row:eq(1) .o_data_cell').text(), "blip666",
"the second row should be updated");
assert.containsNone(list, '.o_data_cell input.o_field_widget', "no field should be editable anymore");
assert.strictEqual(document.activeElement, list.$('.o_data_row:eq(0) .o_data_cell:eq(1)')[0],
"focus should be given to the most recently edited cell after confirm");
list.destroy();
});