From b889e4b3e6d531ccb0e8f4107b50f1131e65e528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 30 Mar 2017 22:03:29 +0200 Subject: [PATCH] [IMP] web: form support for tab navigation The new form view does not really work well with the TAB key. This is partly caused by the fact that the tab event is preventdefaulted. With this commit, we reintroduce a basic navigation with TAB and shift+TAB. --- .../static/src/js/fields/abstract_field.js | 2 +- .../static/src/js/views/form/form_renderer.js | 38 +++++++++++++++++++ addons/web/static/test/views/form_tests.js | 35 +++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js index e4f5ef9d9f8..01de5fb334c 100644 --- a/addons/web/static/src/js/fields/abstract_field.js +++ b/addons/web/static/src/js/fields/abstract_field.js @@ -348,7 +348,7 @@ var AbstractField = Widget.extend({ */ _onKeydown: function (event) { if (event.which === $.ui.keyCode.TAB) { - this.trigger_up('move_next'); + this.trigger_up(event.shiftKey ? 'move_previous' : 'move_next'); event.preventDefault(); } }, diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 2370b1af19a..751923c3b9f 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -15,6 +15,10 @@ var FIELD_CLASSES = { return BasicRenderer.extend({ className: "o_form_view", + custom_events: { + move_next: '_onMoveNext', + move_previous: '_onMovePrevious', + }, /** * @override method from BasicRenderer * @param {Object} params @@ -716,6 +720,40 @@ return BasicRenderer.extend({ }); }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * When someone presses TAB in a widget, it is nice to be able to go to the + * next widget, especially since the TAB key event is preventDefaulted + * + * @private + * @param {OdooEvent} event + */ + _onMoveNext: function (event) { + event.stopPropagation(); + var index = this.widgets.indexOf(event.target); + if (index + 1 < this.widgets.length) { + this.widgets[index + 1].activate(); + } + }, + /** + * When someone presses SHIFT+TAB in a widget, it is nice to be able to go + * back to the previous widget, especially since the TAB key event is + * preventDefaulted + * + * @private + * @param {OdooEvent} event + */ + _onMovePrevious: function (event) { + event.stopPropagation(); + var index = this.widgets.indexOf(event.target); + if (index >= 1) { + this.widgets[index - 1].activate(); + } + }, }); }); diff --git a/addons/web/static/test/views/form_tests.js b/addons/web/static/test/views/form_tests.js index 66d9d64090c..3140310cc82 100644 --- a/addons/web/static/test/views/form_tests.js +++ b/addons/web/static/test/views/form_tests.js @@ -2110,5 +2110,40 @@ QUnit.module('Views', { form.destroy(); }); + + QUnit.test('navigation with tab key in form view', function (assert) { + assert.expect(2); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '
', + res_id: 2, + }); + + // go to edit mode + form.$buttons.find('.o_form_button_edit').click(); + + // focus first input, trigger tab + form.$('input[name="foo"]').focus(); + form.$('input[name="foo"]').trigger($.Event('keydown', {which: $.ui.keyCode.TAB})); + assert.ok($.contains(form.$('div[name="bar"]')[0], document.activeElement), + "bar checkbox should be focused"); + + // simulate shift+tab on active element + $(document.activeElement).trigger($.Event('keydown', {which: $.ui.keyCode.TAB, shiftKey: true})); + assert.strictEqual(document.activeElement, form.$('input[name="foo"]')[0], + "first input should be focused"); + + form.destroy(); + }); }); });