[Project_owners] capturing keypress and handing to default listener

eric.jung at yahoo.com eric.jung at yahoo.com
Tue Sep 26 09:54:06 EDT 2006


From: HJ van Rantwijk <bugs4hj at aim.com>
> Ok, and what was the problem?

Well, there was more than one. Your question as to whether the function was returning false lighted a spark in my head. To summarize the problem again: I wanted to implement custom behavior for certain keypresses (arrow keys and numbers) in a dialog. For every other keypress (e.g., ESC, alt-F4 (which on Windows closes the dialog), etc.), I wanted the default listener to be used.

One of the problems was that I was implicitly returning false/null from some branches because the function wasn't always explicitly returning a value. So now I'm always explicitly returning a value, and I've added stopPropagation() and preventDefault() in the appropriate places, even though I don't think both function calls are necessary.

The other problem was that event.charCode is always 0 when the arrow keys are pressed (and perhaps for any non-displayable character). When event.charCode is 0, we should look to event.keyCode for the pressed key. The event.which property/attribute isn't populated for arrow keys, contrary to the documentation which IIRC states that event.which should ALWAYS be populated with either event.charCode or event.keyCode.

The final handler is this, with onkeypress="onKeyPress(event)" as an attribute on the <dialog/>:

function onKeyPress(evt) {
  if (!isNaN(evt.charCode)) { // if it's a number, process it. Probably should conditionally check evt.keyCode since we use it below!
    if (evt.charCode) {
        // select specific row in tree corresponding to the pressed number
        var row = parseInt(evt.charCode-KeyboardEvent.DOM_VK_0)-1;
        row > -1 && row <= accountsTree.view.rowCount-1 &&
          accountsTree.view.selection.select(row);
    }
    else if (evt.keyCode) {
        var handled;
        switch(evt.keyCode) {
          case KeyboardEvent.DOM_VK_UP:
          case KeyboardEvent.DOM_VK_LEFT:
            // move tree selection up one row
            accountsTree.currentIndex>0 && accountsTree.view.selection.select(accountsTree.currentIndex-1);
            handled = true;
            break;
          case KeyboardEvent.DOM_VK_DOWN:
          case KeyboardEvent.DOM_VK_RIGHT:  
              // move tree selection down one row
              accountsTree.currentIndex<accountsTree.view.rowCount-1 &&                
                 accountsTree.view.selection.select(accountsTree.currentIndex+1);
              handled = true;              
        }
    }
    if (handled) {
        evt.stopPropagation();
        evt.preventDefault();
        return false;
    }
  }
  return true;
}






More information about the Project_owners mailing list