tags:

views:

988

answers:

5

The behavior I'm trying to prevent is after a user clicks on a button, the button retains focus, and then if the user hits the space key, the button fires again. So I thought it could be solved either by setting the focus elsewhere, or by having the button ignore the space key. I've tried adding the following keyDown event listener on the button, but it didn't work.

private function btn_keyDown(event:KeyboardEvent):void {
  // try to ignore spaces, i.e. don't click on SPACE when it has focus
  if (event.keyCode == Keyboard.SPACE) {
  }
}

I tried changing focus by doing the following, at the end of the function that's called when the button is clicked:

stage.focus = parent;

but that didn't work either.

+1  A: 

Try adding event.stopPropogation() to your handler inside the "if"

artemb
A: 

The click handler is fired before any keyup handlers bound to the button tag, so there is no way to cancel it. One way you could do what you want is to set a flag whether the event was caused by pressing the space button, or if it was from a click.

private var spacePressed:Boolean = false;

private function onKeyDown(event:KeyboardEvent):void {
    if (event.keyCode == Keyboard.SPACE) {
        spacePressed = true;
    }
}

private function onKeyUp(event:KeyboardEvent):void {
    if (event.keyCode == Keyboard.SPACE) {
        spacePressed = false;
    }
}

private function doSomething():void {
    if (spacePressed)
        return;
    // Normal handling...
}

 

<mx:Button label="Button"
    keyDown="onKeyDown(event);"
    keyUp="onKeyUp(event);"
    click="doSomething();"/>
MizardX
A: 

Space button is handled inside Button's keyDownHandler, so simply override it with empty body and it'll solve the problem. Like this:

package test
{
import mx.controls.Button;
import flash.events.KeyboardEvent;

public class NoSpaceButton extends Button
{
    public function NoSpaceButton()
    {
     super();
    }

    override protected function keyDownHandler(event:KeyboardEvent):void
    {
    }

}
}
Hrundik
+3  A: 

You'll want to create a custom button component and override the keyDownHandler. But, if you want to pick the button(s) to be stopped, you need to add a conditional to the code. This is what it should look like:

package Sandbox
{
    import mx.controls.Button;
    import flash.events.KeyboardEvent;

    public class KeyButton extends Button
    {
     public function KeyButton()
     {
      super();
     }

     protected override function keyDownHandler(e : KeyboardEvent) : void {
      if (e.keyCode == 32) { // Spacebar
       return;
      }
      else if (e.keyCode == 67) { // Letter C
       this.parentApplication.setStyle ("backgroundColor", "#00aa00");
      }

      super.keyDownHandler (e);
     }

    }
}

The advantage of this is that other keys will still work, like Enter, or you can add more conditionals for different keys if, say, you wanted to change the color of the button if you pressed C or whatever.

And while we're at it, there is a difference between KeyboardEvent.keyCode and charCode. keyCode is the ID of the key on the physical keyboard, which means that lowercase c and capital C are the same (keyCode == 67). charCode, on the other hand, is the address of the character in the ASCII table, so c and C are different (C is 67 while c is 99). keyCode is case-insensitive, in short.

Oh, yes. And should you need to check the key and char codes of a key (including arbitary ones like Backspace), check out this page the good folks at Adobe made.

I also made an application to illustrate this. It's a standard Flex Builder project, but the source is in the src folder if you don't have it. Launch the application, and click the button to focus it. Some text should appear over the button, courtesy of the button's click event. While it has focus, press Spacebar, which should fire the click event and print more text, but nothing happens! Now, press the c key to change the background color of the application. Neat, eh?

You can find the source here.

Aethex
A: 

I had the same problem but found a better solution that doesn't involve custom button classes or variable volleyball.

If you don't care about your button being part of the tab order, simply set the "focusEnabled" property to FALSE and this will stop the space bar (and enter button) from firing the button's click event.

Brian Lenzo