Ext


Go Back   Ext JS Forums > Ext JS Community Forums (2.0) > Ext 2.x: Bugs

Reply
 
Thread Tools
  #11  
Old 12-16-2008, 08:22 PM
mmusson mmusson is offline
Ext JS Premium Member
 
Join Date: Nov 2007
Location: Centreville, VA
Posts: 58
mmusson is on a distinguished road
Default Prevent TAB key from bypassing modal window

I have been looking at this issue and come up with the following approach. Along with the code below you need to define the tabIndex configuration option for all the components you want included in the tabbing order.

The code works in FF3 and IE7.

Ext.override(Ext.Window, {
   handleTabs : true,

   initEvents : Ext.Window.prototype.initEvents.createInterceptor(function () {
      if (this.handleTabs === true) {
         this.keys = [].concat(this.keys || [], { key : Ext.EventObject.TAB, fn : this.onTAB, scope : this });
      }
   }),

   onTAB : function (keyCode, e) {
      e.stopEvent();
      
      // TAB moves forward through the order. SHIFT-TAB moves backward through the order.
      var backward = e.shiftKey;

      // Get the set of controls that have a defined tabIndex >= 0. Sort them ascending or descending depending
      // on whether we are moving the focus forward or backward.
      var elements = Ext.query('[tabIndex][tabIndex!=-1]', this.el.dom).sort(function (a, b) {
         return backward ? b.tabIndex - a.tabIndex : a.tabIndex - b.tabIndex;
      });
      
      // We cannot determine the next element in the order if there are no elements with a defined tabIndex.
      if (elements.length === 0) {
         return;
      }
      
      // Get the tabIndex from the control that had focus when TAB/SHIFT-TAB was pressed
      var currentIndex = e.getTarget().tabIndex || 0;

      // Check each element to see if it is the next one in the ordering      
      for (var i=0; i<elements.length; i++) {
         var el    = elements[i];
         var index = el.tabIndex;
         
         if ((backward && index < currentIndex) || (!backward && index > currentIndex)) {
            el.focus();
            return;
         }
      }
      
      // Since no element was the next in the ordering, loop around to other end of the ordering
      elements[0].focus();
   }
});
Reply With Quote
  #12  
Old 02-23-2009, 04:15 PM
dj dj is offline
Ext JS Premium Member
 
Join Date: Mar 2007
Location: Germany
Posts: 497
dj is on a distinguished road
Default

One could also install a global focus/blur handler to enforce that the focus stays in the modal window.

YUI did this:
http://yuiblog.com/blog/2008/10/07/onfocus-onblur/
__________________
Daniel Jagszent
dɐɳiel@ʝɐgszeɳt.de <- convert to plain ASCII to get my email address
Reply With Quote
  #13  
Old 03-29-2009, 02:53 PM
kavih7 kavih7 is offline
Ext User
 
Join Date: Sep 2007
Posts: 22
kavih7 is on a distinguished road
Default Solution

I was running into the same problem with my application and I use this code. If the tab key is pressed and the active window is modal (if any window), it checks to see if the activeElement (the one with focus) is a child of that window. If so, we are good. If not, get the first child of the window that can receive focus and focus it:

Ext.onReady(function()
{
    Ext.getBody().on('keyup', function(e, t)
    {
        if (e.TAB == e.getKey())
        {
            var top_win = Ext.WindowMgr.getActive();
            
            if (top_win && top_win.modal)
            {
                if (!top_win.getEl().contains(document.activeElement))
                {
                    var found = false;
                    var first_focus = top_win.findBy(function(cmp, win)
                    {
                        var ti = cmp.getEl().dom.tabIndex;
                        
                        if('hidden' != cmp.getXType() && !cmp.hidden && ti >= 0 && !found)
                        {
                            found = true;
                            return true;
                        }
                        
                        return false;
                    });
                    
                    if (first_focus.length > 0)
                    {
                        first_focus[0].focus(true);
                    }
                    else
                    {
                        top_win.focus();
                    }
                }
            }
        }
    }, this);
});
My application only runs on Firefox, so the "document.activeElement" should be cross-browser tested for your application(s) if they use other browsers besides Firefox.

Let me know if you find any bugs/efficiency upgrades
Reply With Quote
  #14  
Old 03-30-2009, 04:48 AM
bearmonger bearmonger is offline
Ext User
 
Join Date: Aug 2007
Posts: 19
bearmonger is on a distinguished road
Default

Can someone from Ext tell us whether this will be implemented in Ext 3.0 release. It seems unusual that we have to add these manual fixes for such a mature library now?
Reply With Quote
  #15  
Old 04-07-2009, 12:00 PM
ext-user ext-user is offline
Ext JS Premium Member
 
Join Date: Jan 2008
Posts: 5
ext-user is on a distinguished road
Default Solution for IE7

Quote:
Originally Posted by kavih7 View Post
I was running into the same problem with my application and I use this code. If the tab key is pressed and the active window is modal (if any window), it checks to see if the activeElement (the one with focus) is a child of that window. If so, we are good. If not, get the first child of the window that can receive focus and focus it:

Ext.onReady(function()
{
    Ext.getBody().on('keyup', function(e, t)
    {
        if (e.TAB == e.getKey())
        {
            var top_win = Ext.WindowMgr.getActive();
            
            if (top_win && top_win.modal)
            {
                if (!top_win.getEl().contains(document.activeElement))
                {
                    var found = false;
                    var first_focus = top_win.findBy(function(cmp, win)
                    {
                        var ti = cmp.getEl().dom.tabIndex;
                        
                        if('hidden' != cmp.getXType() && !cmp.hidden && ti >= 0 && !found)
                        {
                            found = true;
                            return true;
                        }
                        
                        return false;
                    });
                    
                    if (first_focus.length > 0)
                    {
                        first_focus[0].focus(true);
                    }
                    else
                    {
                        top_win.focus();
                    }
                }
            }
        }
    }, this);
});
My application only runs on Firefox, so the "document.activeElement" should be cross-browser tested for your application(s) if they use other browsers besides Firefox.

Let me know if you find any bugs/efficiency upgrades

Thanks a lot for this solution. I had to modify it a little bit to work in IE7:

Ext.onReady(function()
{
    Ext.getBody().on('keyup', function(e, t)
    {
        if (e.TAB == e.getKey())
        {
            var top_win = Ext.WindowMgr.getActive();
            
            if (top_win && top_win.modal)
            {
                if (!top_win.getEl().contains(document.activeElement))
                {
                    var found = false;
                    var first_focus = top_win.findBy(function(cmp, win)
                    {
                        var ti = cmp.getEl().dom.tabIndex;
                        
                        if('hidden' != cmp.getXType() && 'panel' != cmp.getXType()&& 
                           'form' != cmp.getXType()&& !cmp.hidden && ti >= 0 && !found)
                        {
                            found = true;
                            return true;
                        }
                        
                        return false;
                    });
                    
                    if (first_focus.length > 0)
                    {
                        first_focus[0].focus(true);
                    }
                    else
                    {
                        top_win.focus();
                    }
                }
            }
        }
    }, this);
});
Reply With Quote
  #16  
Old 05-26-2009, 05:42 PM
dbassett74 dbassett74 is offline
Ext User
 
Join Date: Jan 2009
Posts: 404
dbassett74 is on a distinguished road
Default

any word on this being an official fix? A Modal window SHOULD contain the Tab key and not let focus go outside of the window. Seems like such basic functionality that should have already been included in the library.
Reply With Quote
Reply

Thread Tools

Posting Rules

Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

All times are GMT -5. The time now is 07:58 PM.

© 2006-2009 Ext, LLC
Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.