Thursday, March 3, 2011

Why does tabbing to a DojoX grid result in a JavaScript "Can't move focus to control" error?

Problem
I've got a number of Dojo components on a page. When the user tries to tab from an input like component to a grid like component, I get a JavaScript "Can't move focus to control" error. The user base uses IE6.

Solution
The first element in the DojoX Grid layout cannot be hidden. If it is hidden, you get a a JavaScript "Can't move focus to control" error. To fix this, I added a row # that displays. See below.

  var gridLayout = [
    new dojox.grid.cells.RowIndex({ name: "row #", 
                                    width: 2, 
                                    styles: "text-align: right;"
                                 }),
    {
      field: "ele_id",
      name: "Element ID",
      styles: "text-align:right;",
      width:5,
      hidden:"true"           
    },
    {
      field: "ele_nm",
      name: "Element Name",
      styles: "text-align:left;",
      width:8          
    }
  ];
From stackoverflow
  • You have to handle the keydown event and listen for character 9 (which is the tab character). To invalidate the event you simply return false when the user presses character 9.

    function handleKeyDown(e)

    {

    var keynum;

    var keychar;

    var numcheck;

    if(window.event) // IE

    {

    keynum = e.keyCode;

    }

    else if(e.which) // Netscape/Firefox/Opera

    {

    keynum = e.which;

    }

    return keynum != 9; ` }`

    Bryan Oakley : You have to deal with shift-tab going in the opposite direction too.
  • <input name="z" onfocus="this.blur()"/>
    
    ARemesal : I think that can be very annoying for the user: he'll try and try again to focus the element, but the focus goes to another element always...
    Diodeus : I agree. I'm just trying to answer the question.
  • I would personally think this type of behavior is a bit annoying. Why are you prohibiting the user from focusing on that field?

    A better solution would be to hide/disable the field until it is ready to have data entered into it. You should also have some text to explain why the field is disabled.

    Edit: The error message you posted has some results on google, but it seems like it could be any number of issues, this one http://www.francoisfaubert.com/2008/03/06/cant-move-focus-to-control/ sounds like it could be a possibility. Check your HTML to see if there are other controls with the same ID on the page.

    happyappa : clarified the issue above. it's to prevent someone from tabbing from an input field to a grid component. what other ways would you suggest handling that?
    Bob : What is this "grid component"?
    happyappa : The Grid I'm using is a DojoX component.
    happyappa : Not an ID issue. Yeah, ineffectively googled, so I thought I'd give it a shot here.
  • You can set Input-Z as a disabled control. Then, when the user tabs into Input-Y and fill it, change Input-Z to enabled. How can you do it:

    <input id="Input-x" type="text" />
    <input id="Input-y" type="text" onChange="document.getElementById('Input_Z').removeAttribute('disabled');" />
    <input id="Input-z" type="text" disabled />
    
  • Preventing tabbing may disrupt partially sighted users who are browsing your site using a screenreader.

    happyappa : i clarified the issue above. thanks for pointing that out. what other ways could you handle something like this?
  • If input Y doesn't accept user input, then don't make it an input field!

    If you're just using this for value display, use a styled <span> or <div> instead.

    Chris : Agreed. There is no reason for a well designed app to have a requirement to disable the tab key. It's like asking "can I disable the back button?" You just don't do it. It's part of the expected standard.
    happyappa : i gave a bad example. the issue is tabbing from an input field to a grid component that can't handle it. i'm trying to prevent the JavaScript error from occurring.
  • Give the component element a tabindex attribute with the value -1

  • After your comments clarifying the issue, I understand you need that user can't focus an element with tab key. Try to add to the element:

    tabindex="-1"

    by example:

    <div id="mygrid" tabindex="-1"> <!-- Some stuff here --> </div>
    

    More information about negative tabindexes: introduction-to-wai-aria

    Edit: More information about ARIA: http://www.w3.org/WAI/intro/aria

  • Regarding the error message: From Fake's tank:

    "odds are you have conflicting ids in your document. Also, remember IE 7 and the previous versions are alone to think a name attribute should be treated like an id."

    So, firstly, this is an IE-specific bug. Secondly, go change your ids. It appears to be something that afflicted some HP html-based software before, and appeared when the users upgraded from IE6 to IE7.

    Regarding the question about disabling focus - just hide any inputs that are unwanted with type=hidden in the tag, and they will cease to be a problem. Never mess about with people's tabbing - it's the one thing that has improved with html over Windows apps.

    Morals of the tale:

    • Do It Properly
    • Microsoft Is Crap At Web Stuff
    • Don't Mess With Standard GUI Behaviour
    happyappa : Thx for pointing out the possibility, but not an id issue.
  • Solution
    The first element in the DojoX Grid layout cannot be hidden. If it is hidden, you get a a JavaScript "Can't move focus to control" error. To fix this, I added a row # that displays. See below.

      var gridLayout = [
        new dojox.grid.cells.RowIndex({ name: "row #", 
                                        width: 2, 
                                        styles: "text-align: right;"
                                     }),
        {
          field: "ele_id",
          name: "Element ID",
          styles: "text-align:right;",
          width:5,
          hidden:"true"           
        },
        {
          field: "ele_nm",
          name: "Element Name",
          styles: "text-align:left;",
          width:8          
        }
      ];
    

0 comments:

Post a Comment