Ext

Improving Application Usability with Ext JS Keyboard Handling

September 23, 2008 by Rich Waters

As Enterprise applications begin moving to the web instead of the desktop many developers may forget about providing key bindings for their applications. Most web applications use the keyboard only for text entry and do not associate particular key combinations with user actions. By providing this type of key handling, particularly for applications which require a lot of data entry, we can improve the end-user experience.

While at a recent client engagement, we wanted to provide a smooth transition for users skilled at working with a legacy ‘green screen’ application to using a new Ext JS version. Part of this transition involved enabling power users to continue navigate the application with the same key handling. By the end-users not having to remove their hands from the keyboard, their efficiency increases substantially. Here’s some insight into how we accomplished the task at hand.

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.

var keys = [];
for(var i = 0;i < buttons.length;i++) {
    var btn = buttons[i];
    // fkey property contains a string referencing the Ext constants (ie: Ext.EventObject.F1)
    var fk = eval(button.fkey);
    btn.handler = this.handleKey.createDelegate(this, [fk]);
 
    keys.push({
        key: fk,
        handler: this.handleKey.createDelegate(this, [fk]),
        stopEvent: true,
        scope: this
    });
}

This implementation demonstrates creating a toolbar and assigning function keys that would perform the same action when the button was clicked or when using the mouse. buttons is an array of button configurations that we pulled from the Json response from the server. The server is sending over a string which references some constants built into the Ext.EventObject for function keys. Since the data comes over as a string we can simply eval it and get the resulting number.

We use a generic handler for all of the click and keypress functions since it is all controlled from the server. createDelegate lets us pass along the key that was pressed so that we can share the same handler function regardless of if the event was a click or a keypress. With the keys array built and our handlers added into the buttons array, we are able to toss these into our Panel configuration and it will do the heavy lifting for us.

tabPanel.add({
    title: 'Test Panel',
    tbar: buttons,
    keys: keys
    ...
});

With our layout in place, adding a tab with our key handlers is pretty simple. The tbar parameter takes our array of Ext.Button configs that were server generated (aside from the handler), and the keys parameter takes an array to pass along to the Ext.KeyMap object.

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 GridPanel. 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.

MyGrid = Ext.extend(Ext.grid.GridPanel,{
...
afterRender : function() {
   MyGrid.superclass.afterRender.call(this);
 
    this.nav = new Ext.KeyNav(this.getEl(),{
        pageDown: this.pagingNav.createDelegate(this,['next']),
        pageUp: this.pagingNav.createDelegate(this, ['prev']),
        home: this.pagingNav.createDelegate(this,['first']),
        end: this.pagingNav.createDelegate(this,['last']),
        scope: this
    });
},
 
pagingNav: function(page) {
    var pt = this.getBottomToolbar();
    if (!pt[page].disabled) {
        pt.onClick(page);
    }
},
...
});

This is a snippet from an extended GridPanel class, and it assumes that there is an Ext.PagingToolbar in place and it is the bottom toolbar (bbar). We could certainly write this code without the PagingToolbar, but it has already done the work to calculate page sizes and has handlers in place for determining the proper load call when skipping backwards/forwards in pages. We create our new Ext.KeyNav object and apply it to the GridPanel’s underlying Ext.Element. KeyNav does the work of assigning handlers to the proper key codes and calls our pagingNav function with the parameter that we bound to it using createDelegate. The pagingNav function merely checks to see if that particular button is disabled, for instance if you’re on the last page, you cannot press the next button again, so we don’t let them “page down” again either. As long as that button is not disabled we act as if the user clicked on the page next button and let the PagingToolbar do it’s magic and load the proper page.

Utilizing these techniques we were able to provide a seamless keyboard navigation experience for our client and their customers migrating from the legacy application to the web application

Getting Started

As you can see, adding custom key handling within an Ext JS application is quite easy. For any custom keys, including function keys, alpha keys with or without modifiers (alt/shift/ctrl) there is Ext.KeyMap. For navigation, arrows, paging, home/end there is Ext.KeyNav. There’s some more handy example code available for each right within the API documentation if you need any further help getting started.

51 Responses to “Improving Application Usability with Ext JS Keyboard Handling”

  1. Ajaxian » Ext JS Key mapping; Keyboard handling as a first class citizen

    [...] 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: [...]

  2. Marco

    How did you override the Function keys in EVERY browser?

  3. Ajax Girl » Blog Archive » Ext JS Key mapping; Keyboard handling as a first class citizen

    [...] 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: [...]

  4. Sebien

    Does this work with Opera?

    In the past, I tryed to make Fx keys work with Opera but some are reserved.
    And more generaly, canceling a key event in Opera proved to be impossible!
    So you can’t bind F5 to any JavaScript function: page will reload.
    For a JavaScript game, I have to make sure the page has no scrollbar because using the direction keys will also scroll the page…

  5. outaTiME at refinn dot com » Blog Archive » Improving Application Usability with Ext JS Keyboard Handling

    [...] Ext JS Blog.) Posted by outaTiME Filed in ExtJS, [...]

  6. outaTiME at refinn dot com » Blog Archive » Ext JS Key mapping; Keyboard handling as a first class citizen

    [...] 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 [...]

  7. Sytze Loor

    Thanks for this wonderful blog post. This will make my application much more user-friendly.
    Some people had questions about overriding the default keys of a browser. I, however, had no problem with overriding the default keys.
    This is what I’ve done:
    [CODE]
    var map = new Ext.KeyMap(element, [{
    key: Ext.EventObject.F1,
    stopEvent: true,
    fn: function() { alert('f1 was pressed'); }
    });
    [/CODE]
    The most important thing here is the stopEvent property. The code above works for me in Firefox 3. I would like to know whether this works in IE, Safari and Opera as well…

  8. Karl Krukow

    // string referencing the Ext constants (ie:Ext.EventObject.F1)
    var fk = eval(button.fkey);

    It is possible to avoid the eval call, which is safter and more performant. For example by doing:

    var fk = eval(Ext.EventObject[button.fkey]);

    where button.fkey would instead be e.g. “F1″.

    /Karl

  9. Javascript News » Blog Archive » Ext JS Key mapping; Keyboard handling as a first class citizen

    [...] 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: [...]

  10. David Bolter

    Great stuff. For many users, the partner to keyboard handling is WAI-ARIA support. Does anyone know if Ext has plans to support this emerging W3C standard for making DHTML apps accessible? (Dojo has support, jQuery is adding it, all major browsers have ot are adding support)

    http://mindforks.blogspot.com/2008/05/accessible-web-interactivity-today.html

    D

  11. Daily del.icio.us for September 24th through September 27th — Vinny Carpenter's blog

    [...] Ext JS - Improving Application Usability with Ext JS Keyboard Handling - As you can see, adding custom key handling within an Ext JS application is quite easy. For any custom keys, including function keys, alpha keys with or without modifiers (alt/shift/ctrl) there is Ext.KeyMap. For navigation, arrows, paging, home/end there is Ext.KeyNav. [...]

  12. Meowmeowz

    Теперь этот форум принадлежит мне. Все вопросы и предложения рассматриваются в icq 477345812

  13. Okonkina

    Там, где наблюдается высокий уровень городского шума, и вместе с тем есть насущная необходимость “делать надолго, качественно и красиво”, настоящим избавлением стали пластиковые окна, Москва в этом плане исключением не является. Пластиковые окна ПВХ завоевали признание среди самых широких масс населения и стали пользоваться большой популярностью как у простых потребителей, так и у профессионалов - строительных и проектных организаций, и касается это не только таких крупных городов, как Москва, Берлин или Нью-Йорк, а всего мира в целом. Легкие, прочные, удобные в эксплуатации, прекрасно зарекомендовавшие себя с самых разных сторон, пластиковые окна стали необходимым атрибутом комфортной жизни. Строгий четкий контур, устойчивость к погодным явлениям и легкость в уходе сначала сделали пластиковые окна ПВХ идеальной деталью офисного или производственного интерьера, но затем, с совершенствованием технологии их изготовления, они пришли и в жилые дома. И если раньше еще могли оставаться какие-то сомнения по поводу того, пускать или не пускать в дом профили ПВХ, то сегодня их нет - современные пластиковые окна не только красивы и высококачественны, но и абсолютно безопасны в экологическом плане.

    окна пвх московская область

  14. Marek987

  15. teakwoodnew

    Продажа Садовой мебели из тика со склада в Москве, парковая мебель из тика, мебель для кафе .
    Раскладные Шезлонги, лежаки, столики, стулья, кресла. Раздвижные столы. Обработано натуральным тиковым маслом. Доступные цены,
    супер качество, прямые поставки со склада. (495) 5435811

  16. Sandip Bhoi

    we are trying to use KeyMap and wanted to override the alt + d trigger and execute the user defined function. It works in IE6,FF3.0 properly and DO NOT WORK in IE7.

    What could be the reason?

    Following is the code snippet used..

    var map = new Ext.KeyMap(document, [
    {
    key: 'd',
    alt: true,
    fn: function(){ alert("D was pressed"); }
    }, {
    key: "abc",
    fn: function(){ alert('a, b or c was pressed'); }
    }, {
    key: "\t",
    ctrl:true,
    shift: false,
    fn: function(){ alert('Control + shift + tab was pressed.'); }
    }
    ]);

  17. Sventin

    Привет. Я новый пользователь на extjs.com и решил сделать небольшой общественный вклад так сказать. Наверное, уже многие знают сайт http://mvmvideo.ucoz.ru
    Там собрано просто огромнейшее количество эротических клипов разной тематики. Большая часть клипов вообще уникальная и найти на тех же трекерах почти нереально. Сайт платный. Я когда-то покупал там доступ на год, но уже посмотрел все клипы и все что мне было нужно - скачал, поэтому отдаю свой доступ на сайт вам, качайте на здоровье, особенно загляните в раздел домашнего видео и видео скрытой камерой - это вообще шедевры. Пароль dfornodfkw

  18. Филипп

    Да, такой блог по-любому надо раскручивать как только можно - что б как можно больше жителей инета о нем узнали! :)

  19. söve

    thanks.

  20. Sarfraz

    Great!

    Thanks
    Sarfraz
    http://www.greepit.com | Open Source Resources

  21. Alexwebmaster

    Hello webmaster
    I would like to share with you a link to your site
    write me here preonrelt@mail.ru

  22. работяга

    Без особого преувеличения можно точно сказать, что пост тему раскрыл на все 100 процентов.

  23. нeжнaя

    Действительно интересно. Некоторые моменты не знал.

  24. cheappower

    Уважаемый автор блога, а вы случайно не из Москвы?

  25. Stypororway

    Вот решил вам немного помочь и послал этот пост в социальные закладки. Очень надеюсь ваш рейтинг возрастет.

  26. helefyv

    Хм, почему-то у меня вместо заголовка блога вопросики…

  27. virabux

    Не стану говорить за остальных, но именно мне этот пoст понравился.

  28. xyyhewy

    Спасибо огромное. Почитал и понравилось. Картинок бы ещё.

  29. vidifyw

    Спасибо за эту информацию, однако осмелюсь внести долю критики, мне кажется автор перестарался с изложением фактов, и статья получилась довольно академичной и “сухой”.

  30. wehygam

    Хорошо пишете. Учились где-то или просто с опытом пришло?

  31. kefasot

    Очень интересно. Но чего-то не хватает. Может быть, стоит добавить каких-нибудь картинок или фото?

  32. kynisaz

    Очень интересно. Но чего-то не хватает. Может быть, стоит добавить каких-нибудь картинок или фото?

  33. jasytep

    Интересно, а почему так редко блог обновляете?

  34. kosihem

    Хорошо пишете. Надеюсь, когда-нибудь увижу нечто подобное и на своем блоге…

  35. ditujih

    Не стану говорить за остальных, но именно мне этот пoст понравился.

  36. zychady

    Спасибо. Уже не первый раз по делу пишете!)

  37. chulato

    Наткнулся случайно на Ваш блог. Теперь стану постоянно просматривать. Надеюсь, не разочаруете и дальше :)

  38. Wretlertors

    Отлично!!! Всем рекомендую!

  39. gigacak

    Интересно, а почему так редко блог обновляете?

  40. xyebony

    Спасибо огромное. Почитал и понравилось. Картинок бы ещё.

  41. kumuvuj

    Очень интересно. Но чего-то не хватает. Может быть, стоит добавить каких-нибудь картинок или фото?

  42. radazuh

    Я извиняюсь, что немного не в тему, а что такое RSS? и ка на него подписаться?

  43. goquiby

    Хорошо пишете. Учились где-то или просто с опытом пришло?

  44. raseapadcak

    Обязательно скажу о вас всем своим друзьям.:-)

  45. Бежен

    Это прям в точку!!! Другими словами и не скажешь! :)

  46. Риски

    Приятно когда можно комментарий оставить. Мне нравится ваш сайт!

  47. gificha

    В точку! Да и вooбще почти во всем с вами согласен.

  48. jynogor

    Добавил в свои закладки. Теперь буду вас намного почаще читать!

  49. kabin

    saolun arkadaslar…..

  50. dimwre

    Скандинавский аукцион – о вид интернет аукциона, при котором товар или услуга выставляется на продажу по минимальной стоимости. Участники аукционных торгов делают ставки с фиксированным шагом. Победителем интернет аукциона считается пособник, сделавший последнюю ставку. Регистрация на интернет аукционе бесплатна + 500 рублей на счет!

  51. Герман

    Спасибо вам за сайт, очень полезный ресурс, мне очень нравится

Leave a Reply

To prove that you're not a bot, please answer this question:



© 2006-2009 Ext, LLC