in Technology

How to stop keyboard event propagation – Flex / JavaScript?

In a Flex application we are building, we want to listen to Ctrl+N to create a new file. The browser listens to the keystroke and opens a new window. We do not want it to open a new window.

This has been a problematic thing for many. I did a lot of research, trial & error, but I still don’t have a solution. I can catch all key events, using some JavaScript, I can also prevent Ctrl+W and Ctrl+S. But not Ctrl+N. Do you have something?

References:

Situations / Test Cases:

  • Should work: Ctrl + N (New), Ctrl + O (Open), Ctrl + W (Close), Ctrl + Q (Quit)
  • Ctrl + C (Copy), Ctrl + V (Paste), Ctrl + X (Cut) – this works with current Flex app. New code must not break it
  • Should work on Windows, Mac, Linux
  • Should work on Firefox, IE, Safari, Chrome
  • What if focus is not in Flex app?
  • What if user goes to another window, comes to our app and presses a keyboard shortcut? (this will lose focus)
  • Will cut / copy / paste from Browser’s Edit menu work?

JavaScript does it:

Flex documentation says:
When handling a key or key combination that the underlying operating system or browser recognizes, the operating system or browser generally processes the event first. For example, in Microsoft Internet Explorer, pressing Control+w closes the browser window. If you trap that combination in your Flex application, Internet Explorer users never know it, because the browser closes before the ActiveX Flash Player has a chance to react to the event.

Notes:

  • KeyboardEvent is non cancelable in Flex.
  • stopImmediatePropagation(), preventDefault(), stopPropagation() – don’t stop the propagation
  • I can detect the keys very well, problem is suppressing the default browser action
  • Don’t want to have a full HTML/JavaScript/ExternalInterface handling like Buzzword. Ideally, want to let Flex handle it’s own events, HTML handle browser events and suppress them.

Any ideas?

TIA!

Write a Comment

Comment

  1. Update:
    I think I am getting closer. Preventing event using JavaScript worked. And I set focus to a textarea in HTML from Flex when I got an accelerator key in Flex. That stopped new window from opening (or other browser/os specific actions).

    Need to clean this up and see if it works always.

    Currently, both Flex and HTML textarea have focus, but neither show whatever I type! They’ve become zombies!

  2. I have a similar problem – want to use the Tab key to open a new VBox container element (similar to accordions) if a user enters the Tab key in the last field in the current container.

    That is now working, but the Tab is being processed twice: once by my own event handler, then a second time, causing it not to move to the SetFocus field, but one the next.

    Did you manage to solve the issue?

    thanks, Johan

  3. Hi Johan,

    Your issues seems more like Flex focus handling issue. Could you not just focus on the current container? That way, the next time tab gets processed, it will go to the correct new container?

    This is a hack, but similar approach worked for me in AdvancedDataGrid where I wanted to create new rows in the grid when you press enter on the last row.

    HTH.

    :Nirav

  4. I’d be interested in knowing if it’s possible to do the opposite – to allow the keystrokes to pass up to the container. I’m tired of Flash stealing CTRL+T from my browser!

  5. I am not sure if you can pass an even to the browser, but you can certainly call a JavaScript function from Flex and that JavaScript function can do what you want.

    Surely, if you wanted to open tabs – I am not sure if that’s something that will happen.

  6. Thanks for the link. The mxml now displays correctly.

    @Nirav. Have you checked BrowserManager and BrowserHistory. I haven’t looked into that but if ctrl-N changes the browserHistory, you should be able to detect it.
    http://www.switchonthecode.com/tutorials/flex-browsermanager-browser-history-and-the-back-button-fun

    @JGarrido. You can pass anything from javascript to Flash or from Flash to javascript. You then need to write the javascript code that will perform the required action. I am not sure you can trigger a ctrl-tab action with javascript, though. I never tried.

    Check out the langref for ExternalInterface. For instance, that’s some code that I use to display debugging messages within a division under the flash application.

    In Flex:
    private static function jsMsg(msg:String):void
    {
    ExternalInterface.call(“sendToJavaScript”, msg);
    }

    On the html page, within a javascript block.
    function sendToJavaScript(val) {
    document.getElementById(‘flash-debug’).innerHTML += val + ”;
    }

    To do the opposite and send stuff from javascript to Flash

    On the html page, in a script block:
    function callToActionscript(flash, str) {
    getFlashMovie(flash).sendToActionscript(str);
    }
    In Flex:
    ExternalInterface.addCallback(“sendToActionscript”, callFromJavaScript);

    function callFromJavaScript(param):void {
    // do something with param
    }

    • We are now using a JavaScript + Hidden Frame approach. This is not full proof, but is working fairly well for us. We take the focus to hidden frame’s input box when user presses a control key, then take the next key input there, and pass it back to Flex. It’s sort of complex…