From 551dc26940f2f33af7fa71c7d1256fe4f2f2fd8f Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Wed, 30 Aug 2017 08:55:03 +0200 Subject: [PATCH] [FIX] web: tab navigation in editable list with create="0" Before this rev., when the user pressed 'TAB' in the last cell of the last row of an editable list with attribute create="0", a new line was added to the list, thus totally ignoring the attribute. Now, it goes back to the first cell of the first row instead, as it was before the new views. Closes #19053 --- .../static/src/js/fields/relational_fields.js | 6 +- .../src/js/views/list/list_controller.js | 6 +- .../js/views/list/list_editable_renderer.js | 7 +- addons/web/static/tests/views/list_tests.js | 75 +++++++++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index e05a53194c3..67218e5decd 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -1063,7 +1063,11 @@ var FieldOne2Many = FieldX2Many.extend({ ev.stopPropagation(); if (this.editable) { - if (!this.creatingRecord) { + if (!this.activeActions.create) { + if (ev.data.onFail) { + ev.data.onFail(); + } + } else if (!this.creatingRecord) { this.creatingRecord = true; this._setValue({ operation: 'CREATE', diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js index 3b74f140e4d..33637e53f52 100644 --- a/addons/web/static/src/js/views/list/list_controller.js +++ b/addons/web/static/src/js/views/list/list_controller.js @@ -313,7 +313,11 @@ var ListController = BasicController.extend({ */ _onAddRecord: function (event) { event.stopPropagation(); - this._addRecord(); + if (this.activeActions.create) { + this._addRecord(); + } else if (event.data.onFail) { + event.data.onFail(); + } }, /** * Handles a click on a button by performing its action. diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index 3cd93bb6e8b..c5f65ecc6e2 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -341,7 +341,12 @@ ListRenderer.include({ if (this.currentRow < this.state.data.length - 1) { this._selectCell(this.currentRow + 1, 0); } else { - this.unselectRow().then(this.trigger_up.bind(this, 'add_record')); + var self = this; + this.unselectRow().then(function () { + self.trigger_up('add_record', { + onFail: self._selectCell.bind(self, 0, 0, {}), + }); + }); } }, /** diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 4b33af9f0a6..2ac373dbcd0 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -19,6 +19,7 @@ QUnit.module('Views', { int_field: {string: "int_field", type: "integer", sortable: true}, qux: {string: "my float", type: "float"}, m2o: {string: "M2O field", type: "many2one", relation: "bar"}, + o2m: {string: "O2M field", type: "one2many", relation: "bar"}, m2m: {string: "M2M field", type: "many2many", relation: "bar"}, amount: {string: "Monetary field", type: "monetary"}, currency_id: {string: "Currency", type: "many2one", @@ -1994,6 +1995,80 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('navigation with tab on a list with create="0"', function (assert) { + assert.expect(4); + + var list = createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '' + + '' + + '', + }); + + assert.strictEqual(list.$('.o_data_row').length, 4, + "the list should contain 4 rows"); + + list.$('.o_data_row:nth(2) .o_data_cell:first').click(); + assert.ok(list.$('.o_data_row:nth(2)').hasClass('o_selected_row'), + "third row should be in edition"); + + // Press 'Tab' -> should go to next line + list.$('.o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(list.$('.o_data_row:nth(3)').hasClass('o_selected_row'), + "fourth row should be in edition"); + + // Press 'Tab' -> should go back to first line as the create action isn't available + list.$('.o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(list.$('.o_data_row:first').hasClass('o_selected_row'), + "first row should be in edition"); + + list.destroy(); + }); + + + QUnit.test('navigation with tab on a one2many list with create="0"', function (assert) { + assert.expect(4); + + this.data.foo.records[0].o2m = [1, 2]; + var form = createView({ + View: FormView, + model: 'foo', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 1, + viewOptions: { + mode: 'edit', + }, + }); + + assert.strictEqual(form.$('.o_field_widget[name=o2m] .o_data_row').length, 2, + "there should be two records in the many2many"); + + form.$('.o_field_widget[name=o2m] .o_data_cell:first').click(); + assert.ok(form.$('.o_field_widget[name=o2m] .o_data_row:first').hasClass('o_selected_row'), + "first row should be in edition"); + + // Press 'Tab' -> should go to next line + form.$('.o_field_widget[name=o2m] .o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(form.$('.o_field_widget[name=o2m] .o_data_row:nth(1)').hasClass('o_selected_row'), + "second row should be in edition"); + + // Press 'Tab' -> should go back to first line as the create action isn't available + form.$('.o_field_widget[name=o2m] .o_selected_row input').trigger({type: 'keydown', which: 9}); + assert.ok(form.$('.o_field_widget[name=o2m] .o_data_row:first').hasClass('o_selected_row'), + "first row should be in edition"); + + form.destroy(); + }); + QUnit.test('edition, then navigation with tab (with a readonly field)', function (assert) { // This test makes sure that if we have 2 cells in a row, the first in // edit mode, and the second one readonly, then if we edit and press TAB,