The OCST respects the keyboard shortcuts defined by the common operating systems and browsers to avoid confusion of the user with divergent shortcuts. Therefore, the CC has a set of shortcuts of its own.
There are several websites that deal with the shortcuts of operating systems and browsers:
The plugin jQuery Hotkeys supports the handling of keyboard events.
Controls have to be put in a useful order so that the user can navigate them via tab key. Therefore they should have an attribute tabindex
to specify the position in the tabbing order.
It must be possible to interact with the OCST with defined shortcuts.
The global shortcuts are defined in ContactRoute.js and can be adapted easily:
... function(Ember, AuthenticatedRoute) { var ContactRoute = AuthenticatedRoute.extend({ needs: ['coBrowse'], shortcuts: { 'alt+b': 'coBrowse', 'alt+i': 'showContactOverview', 'alt+q': 'endContact', 'alt+c': 'showCouponPage', 'alt+o': 'showQuickOrderPage', 'alt+l': 'showStoreFinder', 'alt+s': 'showProductSearch', }, actions: { coBrowse: function coBrowse() { ... } showContactOverview: function showContactOverview() { ... } endContact: function endContact() { ... } showCouponPage: function showCouponPage() { ... } showQuickOrderPage: function showQuickOrderPage() { ... } showStoreFinder: function showStoreFinder() { ... } showProductSearch: function showProductSearch() { ... } }, ...
The template Contact.jsp contains the global links with the their defined shortcuts. The shortcuts are appended to the link wrapped in a <kbd> which handles this switchable visibility.
<li class="pull-right"> <a href="#"{{action "coBrowse"}}><span class="glyphicon glyphicon-new-window"></span> {{i18n "co_browse.button.label"}} <kbd>Alt+b</kbd></a> </li> {{#link-to 'contact.overview' tagName="li"}} {{#link-to 'contact.overview' name="overviewPage"}}{{i18n "application.overview.link"}}<kbd>Alt+i</kbd>{{/link-to}} {{/link-to}} {{#link-to 'quickOrder' tagName="li"}} {{#link-to 'quickOrder' name="linkOrderPage"}}{{i18n "application.quick_order.link"}}<kbd>Alt+o</kbd>{{/link-to}} {{/link-to}} {{#link-to 'promotions' tagName="li"}} {{#link-to 'promotions' name="linkCouponPage"}}{{i18n "application.promotions.link"}}<kbd>Alt+c</kbd>{{/link-to}} {{/link-to}} {{#link-to 'contact.storeFinder' tagName="li"}} {{#link-to 'contact.storeFinder' name="linkStoreFinderPage"}}{{i18n "application.store_finder.link"}}<kbd>Alt+l</kbd>{{/link-to}} {{/link-to}}
Key Event | Action |
---|---|
Alt+K | Shows all possible shortcuts of the page (shortcut hints) For example before using this shortcut: For example after using this shortcut: |
Alt+Q | Finishes the current session |
Key Event | Action |
---|---|
Alt+e | Show the extended search |
Enter | Search for a customer |
In order to support navigation with arrow keys, a concept has been implemented that allows developers to define groups of selectable elements. Within a group the selected entry can be changed by using the up and down arrow keys (↑,↓).
If a page contains multiple groups the keys left and right (←,→) can be used to switch the group. A selected entry can be opened or confirmed using the Enter key.
This general behavior is implemented in the main JavaScript cc-app.js:
// General key up/down handler for arrows $(document).keydown(function(e){ if(e.which == 37) { // left var currentFocusGroupItems = $('[data-keyboard-focus-group]'); var currentFocusGroup = $(':focus').closest('[data-keyboard-focus-group]'); var prevIndex = ( currentFocusGroupItems.index(currentFocusGroup) - 1); if (prevIndex < 0) prevIndex = 0; $(currentFocusGroupItems).eq(prevIndex).find('[data-keyboard-focus]:first').focus(); } if(e.which == 39) { // right var currentFocusGroupItems = $('[data-keyboard-focus-group]'); var currentFocusGroup = $(':focus').closest('[data-keyboard-focus-group]'); var nextIndex = ( currentFocusGroupItems.index(currentFocusGroup) + 1); $(currentFocusGroupItems).eq(nextIndex).find('[data-keyboard-focus]:first').focus(); } if(e.which == 38) { // up var currentFocusElement = $(':focus'); var currentFocusGroupItems = currentFocusElement.closest('[data-keyboard-focus-group]').find('[data-keyboard-focus]'); var prevIndex = ( currentFocusGroupItems.index(currentFocusElement) - 1); if (prevIndex < 0) prevIndex = 0; $(currentFocusGroupItems).eq(prevIndex).focus(); } if(e.which == 40) { // down var currentFocusElement = $(':focus'); var currentFocusGroupItems = currentFocusElement.closest('[data-keyboard-focus-group]').find('[data-keyboard-focus]'); var nextIndex = ( currentFocusGroupItems.index(currentFocusElement) + 1); $(currentFocusGroupItems).eq(nextIndex).focus(); } }).keyup(function(e){ if(e.which == 13) { // enter $(':focus').click(); } });
To define an focus group container any container element (like a <div>
) has to be marked with the attribute data-keyboard-focus-group=""
.
Within this container the selectable items must be attributed with data-keyboard-focus=""
and they additionally should have a tabindex.
As mentioned above it is possible two have multiple focus group containers at one page. Therefore, multiple <div>
containers can be defined.
<!--- Define a data-keyboard-focus-group ---> <div class="row" data-keyboard-focus-group=""> <a href="#" tabindex="-1" data-keyboard-focus=""> {{show-address address=selectedCommonShipToAddress}} </a> <a href="#" tabindex="-1" data-keyboard-focus=""> {{show-address address=selectedInvoiceToAddress}} </a> ... </div> <!--- Define another data-keyboard-focus-group ---> <div class="row" data-keyboard-focus-group=""> ... </div>
EmberJS is able to define keyboard events onmost of the HTML elements.
Testing the existing keyboard events is possible and as easy as it could be.
Go to the view where the element is contained in and add a keyDown
event the the view.
CCApp.ServiceRequestView = Ember.View.extend({ keyDown: function(e) { if (e.keyCode == 85) { this.get('controller').send('assignCustomer'); return false; } } });
Note
Events will be triggered only when the focus is on a HTML input element.
There is an alternative option for defining global keyboard events.
$(document).bind('keydown', 's', function (evt) { $("[name='customerSearch']").click(); console.log("Customer link " + $("[name='customerSearch']").attr('href') + " clicked!"); return false; });
If you want to test mouse or keyboard events in QUnit, you have to use one of the following code snippets.
// click the given element click('[data-testing-id="organization"]'); andThen(function() { // assertion area }); // fire the keydown event with the keycode '13' on the given element keyEvent('[data-testing-id="organization"]', 'keydown', 13); andThen(function() { // assertion area });
Click tests based on Geb and Spock can also test keyboard interactions using the following code snippet:
$("input", name: "firstName") << Keys.chord(Keys.CONTROL, "P")