[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.
This commit is contained in:
Géry Debongnie
2017-04-11 19:44:38 +02:00
committed by Aaron Bohy
parent 11a17f7bb9
commit b889e4b3e6
3 changed files with 74 additions and 1 deletions
@@ -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();
}
},
@@ -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();
}
},
});
});
@@ -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: '<form string="Partners">' +
'<sheet>' +
'<group>' +
'<field name="foo"/>' +
'<field name="bar"/>' +
'</group>' +
'</sheet>' +
'</form>',
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();
});
});
});