diff options
| author | Vincent Schippefilt <vsc@odoo.com> | 2018-01-29 10:39:28 +0100 |
|---|---|---|
| committer | Vincent Schippefilt <vsc@odoo.com> | 2018-04-10 09:39:08 +0200 |
| commit | 02a063fd73d662bfe175db03aad96685543c5ca9 (patch) | |
| tree | 50c820ba6abd8861f8d9c72d049b0833add1a2e6 /addons/web/static/tests/fields/relational_fields_tests.js | |
| parent | 4ba6d2a405c7362986e8a09702e6228887632ea1 (diff) | |
[IMP] web: keyboard navigation in form view
The goal of this commit is to allow fast entry of the same model using
the keyboard for navigating through the form once, by blocking the user
from advancing in the form if there is a required field or once they
went through the form once to get them to a primary action (button)
This commit includes the following changes
1) Enable moving forward from field to field using the TAB key
2) Entering the one to many and many to many using the TAB key
a. When entering it, set the focus on the "add new line" link or
button
b. When adding a new line, set the focus on the field visible
editable field of the new line
c. Discard adding a new line with ESC key
d. If the user leaves the first field empty and uses TAB, we
will cancel the adding of a new line and move to the next
field of the form
3) When a field is required and not filled in, do not allow the user
to move out of the field using the TAB key (the user is still
allowed to use the mouse though), mark the field as invalid
instead
4) After going though the form once, using the TAB key on the last
field will move the focus to the first primary button of the page
5) When the focus is on a primary button (EDIT/SAVE), the user cannot
move the focus forward using the TAB key. Hitting TAB again will
display a tooltip telling to hit ENTER to activate the button.
The mouse is still available to move the focus.
6) When the user saves, the focus is placed on the first primary
button of the form renderer (like VALIDATE for a new invoice)
7) On dialogs, primary buttons should stop the users from moving out
of them, and showing a popup if the user tries
8) When closing a dialog, the focus will be moved back to the widget
that opened it.
This commit does not include the following features
1) Navigation with the keyboard on a selection one to man
2) Navigate between tabs in a form using the keyboard
3) Cancelling the adding of a new line in a many to many using the
ESC key do not set the focus correctly
4) Enhancing the focusses fields (like blue underline)
Diffstat (limited to 'addons/web/static/tests/fields/relational_fields_tests.js')
| -rw-r--r-- | addons/web/static/tests/fields/relational_fields_tests.js | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js index 072dd965d52..1a9576edd75 100644 --- a/addons/web/static/tests/fields/relational_fields_tests.js +++ b/addons/web/static/tests/fields/relational_fields_tests.js @@ -11251,6 +11251,219 @@ QUnit.module('relational_fields', { form.destroy(); }); + + QUnit.module('TabNavigation'); + QUnit.test('when Navigating to a many to one with tabs, it receives the focus on the add new line link', function (assert) { + assert.expect(3); + + var form = createView({ + View: FormView, + model: 'partner', + viewOptions: { + mode: 'edit', + }, + data: this.data, + arch:'<form string="Partners">' + + '<sheet>' + + '<group>' + + '<field name="qux"/>' + + '</group>' + + '<notebook>' + + '<page string="Partner page">' + + '<field name="turtles">' + + '<tree editable="bottom">' + + '<field name="turtle_foo"/>' + + '</tree>' + + '</field>' + + '</page>' + + '</notebook>' + + '</sheet>' + + '</form>', + res_id: 1, + }); + + assert.strictEqual(form.$el.find('input[name="qux"]')[0], + document.activeElement, + "initially, the focus should be on the 'qux' field because it is the first input"); + form.$el.find('input[name="qux"]').trigger($.Event('keydown', { + which: $.ui.keyCode.TAB, + keyCode: $.ui.keyCode.TAB, + })); + assert.strictEqual(assert.strictEqual(form.$el.find('.o_field_x2many_list_row_add>a')[0], + document.activeElement, + "after tab, the focus should be on the many2one on the add new line")); + + form.destroy(); + }); + + QUnit.test('when Navigating to a many to one with tabs, it places the focus on the first visible field', function (assert) { + assert.expect(3); + + var form = createView({ + View: FormView, + model: 'partner', + viewOptions: { + mode: 'edit', + }, + data: this.data, + arch:'<form string="Partners">' + + '<sheet>' + + '<group>' + + '<field name="qux"/>' + + '</group>' + + '<notebook>' + + '<page string="Partner page">' + + '<field name="turtles">' + + '<tree editable="bottom">' + + '<field name="turtle_bar" invisible="1"/>'+ + '<field name="turtle_foo"/>' + + '</tree>' + + '</field>' + + '</page>' + + '</notebook>' + + '</sheet>' + + '</form>', + res_id: 1, + }); + + assert.strictEqual(form.$el.find('input[name="qux"]')[0], + document.activeElement, + "initially, the focus should be on the 'qux' field because it is the first input"); + form.$el.find('input[name="qux"]').trigger($.Event('keydown', { + which: $.ui.keyCode.TAB, + keyCode: $.ui.keyCode.TAB, + })); + document.activeElement.click(); + assert.strictEqual(assert.strictEqual(form.$el.find('input[name="turtle_foo"]')[0], + document.activeElement, + "after tab, the focus should be on the many2one")); + + form.destroy(); + }); + + QUnit.test('when Navigating to a many to one with tabs, not filling in the first field and hitting tab, we should not add a first line but navigate to the next control', function (assert) { + assert.expect(3); + + this.data.partner.records[0].turtles = []; + + var form = createView({ + View: FormView, + model: 'partner', + viewOptions: { + mode: 'edit', + }, + data: this.data, + arch:'<form string="Partners">' + + '<sheet>' + + '<group>' + + '<field name="qux"/>' + + '</group>' + + '<notebook>' + + '<page string="Partner page">' + + '<field name="turtles">' + + '<tree editable="bottom">' + + '<field name="turtle_foo"/>' + + '<field name="turtle_description"/>' + + '</tree>' + + '</field>' + + '</page>' + + '</notebook>' + + '<group>' + + '<field name="foo"/>' + + '</group>' + + '</sheet>' + + '</form>', + res_id: 1, + }); + + assert.strictEqual(form.$el.find('input[name="qux"]')[0], + document.activeElement, + "initially, the focus should be on the 'qux' field because it is the first input"); + form.$el.find('input[name="qux"]').trigger($.Event('keydown', { + which: $.ui.keyCode.TAB, + keyCode: $.ui.keyCode.TAB, + })); + + $(document.activeElement).trigger($.Event('keydown', {which: $.ui.keyCode.TAB})); + + assert.strictEqual(assert.strictEqual(form.$el.find('input[name="foo"]')[0], + document.activeElement, + "after tab, the focus should be on the many2one")); + + form.destroy(); + }); + + QUnit.test('when Navigating to a many to one with tabs, editing in a popup, the popup should receive the focus then give it back', function (assert) { + assert.expect(4); + + this.data.partner.records[0].turtles = []; + + var form = createView({ + View: FormView, + model: 'partner', + viewOptions: { + mode: 'edit', + }, + data: this.data, + arch:'<form string="Partners">' + + '<sheet>' + + '<group>' + + '<field name="qux"/>' + + '</group>' + + '<notebook>' + + '<page string="Partner page">' + + '<field name="turtles">' + + '<tree>' + + '<field name="turtle_foo"/>' + + '<field name="turtle_description"/>' + + '</tree>' + + '</field>' + + '</page>' + + '</notebook>' + + '<group>' + + '<field name="foo"/>' + + '</group>' + + '</sheet>' + + '</form>', + res_id: 1, + archs: { + 'turtle,false,form': '<form><group><field name="turtle_foo"/><field name="turtle_int"/></group></form>', + }, + }); + + assert.strictEqual(form.$el.find('input[name="qux"]')[0], + document.activeElement, + "initially, the focus should be on the 'qux' field because it is the first input"); + form.$el.find('input[name="qux"]').trigger($.Event('keydown', { + which: $.ui.keyCode.TAB, + keyCode: $.ui.keyCode.TAB, + })); + + assert.strictEqual(form.$el.find('.o_field_x2many_list_row_add a')[0], + document.activeElement, + "after tab, the focus should be on the add new line link"); + + form.$el.find('.o_field_x2many_list_row_add a').trigger($.Event('keydown', { + which: $.ui.keyCode.ENTER, + keyCode: $.ui.keyCode.ENTER, + })); + + assert.strictEqual($.find('input[name="turtle_foo"]')[0], + document.activeElement, + "after enter, the focus should be in the popup, in the first input field"); + + $('input[name="turtle_foo"]').trigger($.Event('keydown', { + which: $.ui.keyCode.ESCAPE, + keyCode: $.ui.keyCode.ESCAPE, + })); + + assert.strictEqual(form.$el.find('.o_field_x2many_list_row_add a')[0], + document.activeElement, + "after escape, the focus should be back on the add new line link"); + + form.destroy(); + }); + }); }); }); |
