View Full Version : Keyboard Navigation - tab-bing into a Grid Panel?

20 Nov 2012, 11:26 AM
I've read forum posts about keyboard navigation in a Grid Panel but haven't been able to find an answer to my question. Hopefully, it's not a difficult one...

How does a user "tab" (with the keyboard) into a Grid Panel and give it focus? Once the grid has focus, the arrow keys are working and I can tab to move to the next component on the window (a button, btw), but can't figure out how to tab "into" the Grid itself.

If this is not automatically there as part of ExtJs 4.1.1 functionality, do I understand correctly that I will need to attach a KeyUp listener to the component "before" the Grid Panel that sets focus to the Grid panel when a tab key is pressed while focus is on it (the component before the Grid Panel, that is)? If so, then I have a different problem... The component before the Grid Panel is a Button, which doesn't listen to key events. I've searched the forums for adding a key listener to a button, but didn't come up with anything. If this is necessary, can someone point toward something that will help me to do it?


22 Nov 2012, 6:21 AM
You can enable the FocusManager and now all components will fire the focus/blur events. You would need to capture the focus event on the grid to get focus on the first cell.

24 Jan 2013, 7:57 AM
@mitchellsimoens could you elaborate your answer a little bit?

The FocusManager is disabled by default (Ext 4.1) however form field components are still focusable and keyboard navigation is working perfectly.

Consider the following simple component hierarchy:



What I want is:
Enable navigating between grid's rows using TAB and SHIFT+TAB keys
When I press TAB while inside textfield2, I want grid's first row to be focused & selected
When I press SHIFT+TAB inside textfield3, I want grid's last row to be focused & selected
So basically what I want is create a user experience where there is a lightweight grid panel that looks more like a list (consider GridList from older versions of Ext) and to the user grid rows are no different than other fields - he navigates over them using the same keys he uses to navigate over other form fields.

I realize that GridPanel and GridView are very complex components and they have their own SelectionModel but maybe there is a way to make it work as I described without too many hacks? I think what we basically need is somehow give tabindex to grid's rows or their inner elements and listen to natural focus event. You think it's a good idea?

UPD Sorry for post formatting, fixed...

19 Mar 2013, 11:59 AM
Well, I have a very nasty solution that I wouldn't recommend to anyone really but if someone else goes through the nightmare I have to try to accomplish this within the ExtJs source itself, they might appreciate an ugly solution rather than none at all. I'm still open to anything better, but I've spent many weeks on this (off and on) and time is running out before we release the pages.

One suggestion in this thread was that we use the FocusManager and this was investigated but did not appear to be feasible in our particular case. I provide some background and explanation as to why this is the case in this post: http://www.sencha.com/forum/showthread.php?257889-Ext.tree.Panel-focus-event-how-s-it-triggered&p=944903&viewfull=1#post944903.

Anyway, my solution (such as it is)...

I added an "afterrender" listener to the containing panel and in the associated function, I get the dom object for the first row (skipping the header row) and adding a tabindex='0' attribute to it. This way, I can tab into the grid/tree and then use the arrow keys, etc. to navigate within it. Further, I set an onfocus and onblur function that adds a dotted border around the grid/tree when that cell has focus to visually indicate the "table" is the current element so the keyboard navigation is enabled.

Here's my ExtJs 4.1.1 code (like I said, 'this' is a bigger Ext.panel.Panel with a border layout where the grid/tree in the "center" region along with other panels of components in the "north" and "south"):

,initComponent: function(){
this.on("afterrender", this.onAfterRender);

,onAfterRenderPanel: function(component,args){
var aDomTr = Ext.getDom(this.id).getElementsByTagName("tr");
for (var i = 0; i < aDomTr.length; i++){
if (aDomTr[i].className.indexOf("x-grid-row") > -1){
aDomTr[i].setAttribute("tabindex", "0");
aDomTr[i].setAttribute("onfocus","Ext.getDom('"+this.id+"').style.border=\'1px dotted\';");