Page 1 of 3 123 LastLast
Results 1 to 10 of 24

Thread: [2.0.1][OPEN] modal dialog can be bypassed by tab pressing

  1. #1
    Ext User
    Join Date
    Jan 2008
    Posts
    41

    Thumbs up [2.0.1][OPEN] modal dialog can be bypassed by tab pressing

    Hi,
    in reply to this thread: http://extjs.com/forum/showthread.php?t=7964. I've search in the Ext 2.0 forum but I haven't found nothing.
    So, I want to share my personal solution to solve the problem relative to MessageBox... any suggestion or improvement is appreciate.

    PRE: Attach a document event listener onkeypress that handle the tab key press. Bind to this function an object that contains your Ext.Window (yourMessageBox.getDialog()) and a variable used to store the current focused button
    POST: This is the code of the function called by the event handler:
    PHP Code:

    function ensureModalWindow(){
        
    this.currentFocused = ((this.currentFocused+1) % 4);
        while (
    this.buttons[this.retrieveButtonType(this.currentFocused)]===undefined){
            
    this.currentFocused = ((this.currentFocused+1) % 4);
        }
        
    this.winbox.defaultButton this.currentFocused;
        
    this.winbox.focus();

    This is the code of retrieveButtonType:
    PHP Code:
    retrieveButtonType: function(btn_index){
            switch (
    btn_index){
                case 
    0:
                    return 
    "ok";
                case 
    1:
                    return 
    "yes";
                case 
    2:
                    return 
    "no";
                case 
    3:
                    return 
    "cancel";
                default: 
    //not used
                    
    return "";
            }    
        }, 
    this.buttons is an object like this:
    PHP Code:
    {ok"label for button ok"cancel:"label for cancel"
    this.currentFocused is the index of the current button that has focus. Initialize it when creating your MessageBox, like:
    PHP Code:
    var msgbox Ext.MessageBox.show({
               
    title:this.title,
               
    msgthis.message,
               
    buttonsthis.buttons
               
    fnthis.boundProcessResult,
               
    iconthis.messageType
           
    });
    this.winbox msgbox.getDialog();
           
    this.winbox.on('hide', function(){
                    
    /* remove tab keypress handler*/
            
    });
           
    this.currentFocused this.focusedButton;
           if (
    this.focusedButton!=-1){ // set default button with focus
                   
    this.winbox.defaultButton this.focusedButton;
                   
    this.winbox.focus();
           } 
    Remember to remove event listner for tab when close the MessageBox.The solution is only applicable with MessageBox... because you know all kind of buttons you can display.

    I hope it was clear!

    Sorry for my english.

  2. #2
    Sencha User
    Join Date
    Apr 2012
    Location
    Austin, Texas
    Posts
    4

    Default

    Thanks, we'll take a look at your suggestions and see if they make sense as a general solution. This is on our list of things to address, but just hasn't made it into a release yet.

  3. #3
    Ext User
    Join Date
    Jan 2008
    Posts
    41

    Default

    OK, thanks for the reply. For me, this is a high priority bug.
    Hope is useful.
    If requested i can give a description more detailed of the solution.

    Bye

  4. #4
    Sencha User
    Join Date
    Nov 2007
    Posts
    243

    Default

    FxMan I hope you realise that modal dialogs can easily just be hidden for example by any browser side css modifier or script modifier!

  5. #5
    Ext User
    Join Date
    Jan 2008
    Posts
    41

    Default

    JamesC... what do you mean exactly?

  6. #6
    Sencha User
    Join Date
    Nov 2007
    Posts
    243

    Default

    Well its not a true modal dialog... I could for example use the IE developer toolbar to hide the mask/dialog and still access the page behind (by changing the styles).

  7. #7
    Sencha User vmorale4's Avatar
    Join Date
    Mar 2007
    Location
    Chicago, IL
    Posts
    189

    Default

    Quote Originally Posted by JamesC View Post
    Well its not a true modal dialog... I could for example use the IE developer toolbar to hide the mask/dialog and still access the page behind (by changing the styles).
    I don't think FxMan is concerned about users *deliberately* changing the Javascript/CSS with a tool like Firebug or the IE developer toolbar. If you think about it, "true" modal windows can also be disabled by overwriting the function that calls them from the Firebug console.

    The issue here is about users *accidentally* changing some important value in the page by using the tab key. Many users are 'click-happy' or 'keyboard-happy', and you want to make sure that it is more difficult to do the "wrong thing".

  8. #8

    Default

    Hi,

    I am using a lot of Modal windows and dialogs and faced this problem. So here's a solution that I am happy with it for the moment. It may be for somebody out there or for Ext team. By the way this solution work for any HTML container element (div, form, etc) that we don't want the focus to out of it. So it work with any kind of window or panel, etc.

    The main idea is to track focusable elements outside our container (window) and return back the focus to our window or any element into it.

    Of course this can be optimized.

    Here is the code:

    Code:
    // some utilities:
    function registerEvent(elem_, eventName_, handler_) {
    	if (elem_.attachEvent) {
    		elem_.attachEvent("on" + eventName_, handler_);
    	} else if (elem_.addEventListener) {
    		elem_.addEventListener(eventName_, handler_, true);
    	}
    }
    function unregisterEvent(elem_, eventName_, handler_) {
    	if (elem_.detachEvent) {
    		elem_.detachEvent("on" + eventName_, handler_);
    	} else if (elem_.removeEventListener) {
    		elem_.removeEventListener(eventName_, handler_, true);
    	}
    }
    var FOCUSABLES = ',a,input,button,submit,'; // personalize focusable HTML elements
    function findFocusable(node_, path_, stopElemId_, result_) {
    	if (!node_) {
    		return;
    	}
    	
    	if (node_.id && stopElemId_ && node_.id == stopElemId_) {
    		trace('findFocusable(): stopped at node id=' +stopElemId_);
    		return;
    	}
    	
    	if (!path_) {
    		path_ = '';
    	}
    	var name = node_.nodeName.toLowerCase();
    	path_ += "/" +name;
    	if (FOCUSABLES.indexOf(','+name+',') > -1) {
    		if (!result_[node_]) {
    			node_._path = path_;
    			result_[node_] = node_;
    		}
    	}
    	if (node_.childNodes) {
    		var nodes = node_.childNodes;
    		for (var i = 0; i < nodes.length; i++) {
    			findFocusable(nodes[i], path_, stopElemId_, result_);
    		}
    	}
    }
    After creating a window or a panel, etc:
    Code:
    var win = new Ext.Window({id:<an id>, ...});
    win._hasFocusedOutOfWindow = function(event_) {
    	trace('Left modal window! Back off.');
    	win.focus(); // require having a default button. we can focus something into the window!
    }	
    win._map = {};			
    win.on('activate', function() {
    	findFocusable(document.body, null, win.id, win._map);
    	for (key in win._map) {
    		var node = win._map[key];
    		trace('set listener on focusable element=' +node._path +'#' +node.id);
    		registerEvent(node, "focus", win._hasFocusedOutOfWindow);
    	}
    });
    win.on('deactivate', function() {
    	for (key in win._map) {
    		var node = win._map[key];
    		trace('removed listener on focusable element=' +node._path +'#' +node.id);
    		unregisterEvent(node, "focus", win._hasFocusedOutOfWindow);
    	}
    });
    Hope this will help.
    Thanks

  9. #9
    Ext User
    Join Date
    Jan 2008
    Posts
    41

    Default

    Quote Originally Posted by vmorale4 View Post
    I don't think FxMan is concerned about users *deliberately* changing the Javascript/CSS with a tool like Firebug or the IE developer toolbar. If you think about it, "true" modal windows can also be disabled by overwriting the function that calls them from the Firebug console.

    The issue here is about users *accidentally* changing some important value in the page by using the tab key. Many users are 'click-happy' or 'keyboard-happy', and you want to make sure that it is more difficult to do the "wrong thing".
    yes... this is what I mean.

    I've developed a solution also for the Modal Window but now I haven't time to write here.
    Just let you know that my solution is similar, in the idea, to the butor solution.
    I register an event handler for the tab keypress and check every time is pressed if the field can be focused.
    Something like this (using prototype function):
    PHP Code:
    function onTabKeyPress(evt){
    var 
    target evt.target evt.target evt.srcElement;
    if (
    target.descendantOf(modal_window_id)){
    return; 
    // allow tab natural next field for field inside modal window
    }else{
    Event.stop(evt); // stop default event
    setFocusOnFirstField();
    }

    Hope is useful.

    Bye bye

  10. #10

    Default

    Quote Originally Posted by FxMan View Post
    yes... this is what I mean.

    I've developed a solution also for the Modal Window but now I haven't time to write here.
    Just let you know that my solution is similar, in the idea, to the butor solution.
    I register an event handler for the tab keypress and check every time is pressed if the field can be focused.
    Something like this (using prototype function):
    PHP Code:
    function onTabKeyPress(evt){
    var 
    target evt.target evt.target evt.srcElement;
    if (
    target.descendantOf(modal_window_id)){
    return; 
    // allow tab natural next field for field inside modal window
    }else{
    Event.stop(evt); // stop default event
    setFocusOnFirstField();
    }

    Hope is useful.

    Bye bye
    Hi,

    This is was my first try before the focus one. The problem with this is that when you get the TAB keypress event and realize that you are outside, it is already too late! The focus is already on an element outside our protected area. If instead of pressing TAB (to be detected and repositionned) you type or press enter, that element will react and results on unwanted behavior!

    A+

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •