Wednesday, September 24th, 2008

Ext JS Key mapping; Keyboard handling as a first class citizen

Category: Sencha, Usability

<>p>I am a strong believe in making the keyboard a first class citizen for your applications, including on the Web. Thus, I was interested to read how Ext JS has keyboard handling that ties into the entire system:

Ext.KeyMap

Ext provides several components that support keyboard navigation out of the box such as GridPanel, ComboBox, and TreePanel. To implement custom keyboard handling, developers can use the Ext.KeyMap and Ext.KeyNav classes to attach keyboard bindings to any component or element they wish.

The first set of keys we wanted to handle was all of the Function keys (F1-12). While most browsers reserve some/all of these keys, with some ext-pertise, we are able to override the default function if need be for our application. The application we were working with was completely dynamic and server driven, so we really couldn’t define all of the handlers ahead of time. This led to us dynamically building an array of key handler configuration objects and passing them all through to our new Ext.KeyMap object.

javascript
< view plain text >
  1. var keys = [];
  2. for(var i = 0;i < buttons.length;i++) {
  3.     var btn = buttons[i];
  4.     // fkey property contains a string referencing the Ext constants (ie: Ext.EventObject.F1)
  5.     var fk = eval(button.fkey);
  6.     btn.handler = this.handleKey.createDelegate(this, [fk]);
  7.  
  8.     keys.push({
  9.         key: fk,
  10.         handler: this.handleKey.createDelegate(this, [fk]),
  11.         stopEvent: true,
  12.         scope: this
  13.     });
  14. }

Ext.KeyNav

The next set of key handling added was some additions to the grid keyboard navigation. The GridPanel has built in key navigation from the RowSelectionModel that it creates. Check out this grid example and select a row, you can then use the arrow keys to move up/down and even hold shift and press down to select a range of rows. We added a simple way to navigate through a large paged data set by extending GrindPanel. The PagingToolbar provides keyboard handling once you’ve focused within the built-in TextField, but we wanted to allow the users to just hit ‘page down’ or ‘end’ when focus was anywhere within the GridPanel and ensure it functions as expected.

  1. MyGrid = Ext.extend(Ext.grid.GridPanel,{
  2. ...
  3. afterRender : function() {
  4.    MyGrid.superclass.afterRender.call(this);
  5.  
  6.     this.nav = new Ext.KeyNav(this.getEl(),{
  7.         pageDown: this.pagingNav.createDelegate(this,['next']),
  8.         pageUp: this.pagingNav.createDelegate(this, ['prev']),
  9.         home: this.pagingNav.createDelegate(this,['first']),
  10.         end: this.pagingNav.createDelegate(this,['last']),
  11.         scope: this
  12.     });
  13. },
  14.  
  15. pagingNav: function(page) {
  16.     var pt = this.getBottomToolbar();
  17.     if (!pt[page].disabled) {
  18.         pt.onClick(page);
  19.     }
  20. },
  21. ...
  22. });

Related Content:

Posted by Dion Almaer at 5:28 am
6 Comments

++++-
4.3 rating from 74 votes

6 Comments »

Comments feed TrackBack URI

I have yet to see a web app where I would like the keyboard setup. Sure, it could be convenient, but so far I’ve only noticed keyboard shortcuts in Google Reader. Reader’s shortcuts interfere with my browser’s own keyboard shortcuts so it’s mostly an annoyance rather than a convenience…

Comment by Jani — September 24, 2008

It seems a tag isn’t closed properly in the post.
Ext.KeyNav

Comment by coolnalu — September 24, 2008

@ Jani,

I think you are missing the point. Keyboard shortcuts may not be a big deal when browsing web pages, which does not require a lot of input, but when it comes to an enterprise level web application it can be used as a very fast input method. If you must force a user to go back and forth with the mouse and the keyboard the user experience is interrupted and and is also highly inefficient.

I agree with you that if the application maps shortcuts to already used shortcuts in the browser it hurts the overall usability of the system, but that is the responsibility of the developer to make sure and map the correct keys.

In my opinion, if you can make a enterprise level application run completely on keyboard you have done a great favor to your customers. (but this is not always possible.)

Comment by VpG — September 24, 2008

Let me see if I can kill this unclosed B tag:
.
@Jani:

That’s a good argument for using keyboard shortcuts well, in appropriate places, more than anything.
.
For the most part, “well” can be defined as being predictable, documented, and unobtrusive (I detailed some good practices for key commands here: http://ajaxian.com/archives/custom-events-as-api-end-points-for-key-bindings-and-more#comment-266726).
.
“Appropriate places” can generally be defined as “applications, not documents”. If your documents have key commands, you’re probably overdoing it; I guess it depends on the nature, size and scope of your document though. I can’t say I haven’t wanted key commands in W3 spec documents, for instance! If your applications don’t have key commands (done well), you’re probably neglecting a UI feature that not only helps users substantially, but that many users expect from applications.
.
It’s this kind of neglect that contributes to the perception that web apps aren’t “real” apps. And serious web app developers would do well to address that.

Comment by eyelidlessness — September 24, 2008

So much for closing the B tag. :(

Comment by eyelidlessness — September 24, 2008

This has been built into SmartClient LGPL for.. I guess 3 and a half years now? Only it’s quite a bit more refined, eg, it works with what people call “live grid” these days (load data on scroll).

http://www.smartclient.com/index.jsp#multipleSelect

It mystifies me when these things receive coverage as though they were new.

BTW the hard part of normalizing keyboard events isn’t the f-keys, it’s the modifier keys. Also solved long ago.

Comment by ckendrick — September 27, 2008

Leave a comment

You must be logged in to post a comment.