I have a webpage with a flash header. In the flash header (block), different dropdownmenus are present together with a 'submit' button.
When the user presses 'enter', i want to submit the form.
However, I can't seem to be able to catch any key :
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownFunc);
root.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownFunc);
optiesPanelNew.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownFunc);
optiesPanelNew.ddOptiesMerk.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownFunc);
function onKeyDownFunc(evt)
{
if (evt.keyCode == Keyboard.ENTER)
{
submitForm();
}
}
This javascript works if the html part of the page (non flash) has focus :
document.body.onkeydown = function theFunction()
{
alert("keydown");
}
Edit: Oh no, the flash file was written in AS2 ... sorry :-/
FYI : the code I ended up using was : (AS2) :
var keyListener:Object = new Object();
keyListener.onKeyDown = function():Void
{
if(Key.getCode()==13)
submitForm();
}
Key.addListener(keyListener);
I think you need to specify the event's type in the handler (i.e. KeyboardEvent) because this way the dispatched object will be cast to a Event object when its instance is passed to the handler. The Event class doesn't have the keyCode property, and subsequently the condition to submit the form is not met. That's why the form doesn't get submitted.
So, try replacing the
function onKeyDownFunc(evt)
line, with
function onKeyDownFunc(evt:KeyboardEvent)
and it should do the trick.
Have a great day.
Related
I want to listen to stage for keyboard event, and I want to catch an event directly when it appears (not in bubbling or target). Why can't I do this?
Actually it seems that I can't use useCapture for keyboard events at all.
I want to open my inner console window by pressing tilda button, and change focus to input field. So, I wrote something like this
public function init(stage:Stage):void
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown);
}
private function onStageKeyDown(event:KeyboardEvent):void
{
event.stopImmediatePropagation();
switch(event.keyCode)
{
case Keyboard.BACKQUOTE:
visible = !visible;
stage.focus = visible ? inputField : stage;
break;
}
}
The problem is, it writes "`" character in my input, which I don't want it to do. So, I decided to try to listen to keyboard event in capture phase to stop its propagation. But it seems that stage can't have capture phase, because there is no nodes before it. How can I handle that situation properly?
To simply answer your question, you can listen for keyboard events on the capture phase.
Most likely, the reason you can't, is because nothing has focus. If nothing has focus in your application then the stage will not get a keyboard event. By default, when a swf runs nothing has focus.
Give an item focus when your application starts (anything besides the stage itself), and the event will come.
public function init(stage:Stage):void
{
stage.focus = this; //assuming this is the document class
stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown, true);
}
Now, to follow up with what you are actually trying to accomplish (aside from your actual question) all you need to do is listen for the right event (TEXT_INPUT). Your answer is close, but it can be much simpler without the need for flags or a key down listener:
stage.focus = this; //give something focus, probably not needed if you have to click the text input in order to input text
//listen on the capture phase for text input
stage.addEventListener(TextEvent.TEXT_INPUT, onStageTextInput, true);
function onStageTextInput(event:TextEvent):void
{
switch(event.text)
{
//if the new text was a backquote or # sign, don't let the event trigger it's normal action
case "`":
case "#":
event.preventDefault(); //prevent default is needed
break;
}
}
I finally found a workaround for this problem.
First of all: handling and stopping KeyboardEvent.KEY_DOWN is NOT preventing TextField from getting input. That's sad because in this case it would be useful, but it seems there is some other reasons for not doing this.
So, what I should do is listen for TextEvent.TEXT_INPUT by inputField
inputField.addEventListener(TextEvent.TEXT_INPUT, onTextInput);
and listen to KeyboardEvent.KEY_DOWN by stage
stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown);
in case I may still want to put tilda of backquote signs in my TextField (for example by coping and pasting them) I decided to use a flag
private function onStageKeyDown(event:KeyboardEvent):void
{
switch(event.keyCode)
{
case Keyboard.BACKQUOTE:
...
inAction = true;
break;
}
}
so when TextEvent.TEXT_INPUTevent fires I can see if that was opening window action or not. And if it is, then preventDefault() behaviour, which means NOT inputting received sign in TextField
private function onTextInput(event:TextEvent):void
{
if(inAction)
{
event.preventDefault();
inAction = false;
}
}
I'm trying to catch when a user presses a "enter" key in a rich editable text field. It wasn't dispatching KeyboardEvent.KEY_DOWN so I found that it dispatches an "enter" key event. That seemed more appropriate but that is not getting dispatched either.
Here is my code:
editableRichTextField.addEventListener(FlexEvent.ENTER, commitTextEditorValues, false, 0, true);
Am I missing something?
NB: This is with Apache Flex 4.14.
I knocked up a sample application for this and it seemed that the RichEditableText does dispatch KeyboardEvent.KEY_DOWN. How are you catching it? The following code:
private function CCH():void
{
richEditableText.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
}
private function KeyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.ENTER)
{
Alert.show("Enter Key Pressed");
}
}
should trigger an alert (where the CCH method is the creation complete handler for the component/application.
You have to set multiline to false for the event to be dispatched. This is not helpful if you need to support multiple lines so you have to use #DaJobat's answer and listen on key down.
editableRichTextField.multiline = false;
I am working on a app using Adobe flash Builder which should pop up a Alert window once a particular event has been triggered.
Another event needs to be called when the Alert box is closed. But I do not see the Alert class in mx.controls library. It seems like the class (which existed in AS2) has been removed from AS3. Is there any other way to accomplish the same functionality?
Thanks,
Pritesh
Yo need to define closeHandler for your Alert control. Checkout the ActionScript 3.0 Reference api from here http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/Alert.html#show()
Use ExternalInterface.
import flash.external.ExternalInterface;
// tell flash what javascript function to listen for, and what flash function to call in response
ExternalInterace.addCallback('onAlertWindowClosed', onPopupClosed);
function openPopUp():void
{
// this conditional prevents errors when running local (yes, this needs uploaded to work)
if(ExternalInterface.available)
{
// this calls a javascript function in your html
ExternalInterface.call('myJavascriptAlertFuntion');
}
}
// this function is called from the javascript callback **onAlertWindowClosed**
function onPopupClosed():void
{
// do something when your popup closes
}
and in the html:
<script type="text/javscript>
// this chunk gets the flash object so you can call its methods
function getFlashMovieObject(movieName)
{
if (window.document[movieName])
{
return window.document[movieName];
}
if (navigator.appName.indexOf("Microsoft Internet") == -1)
{
if (document.embeds && document.embeds[movieName])
return document.embeds[movieName];
}
else
{
return document.getElementById(movieName);
}
}
// function that is called from flash
function myJavascriptAlertFuntion()
{
alert("Hey! Yeah you there!");
}
// call this when you want to tell flash you are closing your popup
function tellFlashMyPopupWindowClosed()
{
// **flashContainer** should be replaced by the name parameter of your flash embed object
var flashMovie = getFlashMovieObject("flashContainer");
flashMovie.onAlertWindowClosed();
}
</script>
To have a popup alert in a Mobile project using MXML and AS3, you need to create a component based off of the SkinnablePopUpContainer from the Sparks components. (Since a simple alert has been conveniently uncluded.)
I learned alot reading up on the SkinnablePopUpContainer in the docs here:
The Spark SkinnablePopUpContainer container
To sum it up, I've created a component in MXML with SkinnablePopUpContainer as the base class. In the View that I want to have the popup to be added to, I create a new instance of the class in Actionscript. I listen to the custom events the buttons in the component will be firing on user response. To show the new popup component, simply call the static method open();. The open() method expects a parent container, and wether or not the popup should be Modal. Modal means that nothing under the component can receive user input.
var alert:SkinnablePopUpContainer = new SkinnablePopUpContainer;
alert.addEventListener( "OK", onOK );
alert.open( this, true );
function onOK(e:Event):void{ trace("User said OK") };
I'll put up some example files later when I can.
I have an input TextField and have a KeyboardEvent.KEY_DOWN even listener on the stage to listen for the Keyboard.ENTER event. The event listener adds the entered text to an array or whatever, and then clears the TextField. The problem is that when the Enter key event fires and the TextField value is set to "", it leaves a carriage return in the TextField and the cursor positioned on the second line. WTF? I've been coding AS2 and AS3 for a LONG time and have never ran into this before. Am I losing my mind? Please help, people! :-)
Example:
var myTextArray:Array = new Array();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
function onKeyDown(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.ENTER){
if(_inputText.text != null){
myTextArray.push(_inputText.text);
}
_inputText.text = "";
}
}
Simply replace KEY_DOWN with KEY_UP. It fixes the problem (for me at least)
Use KEY_DOWN -> Your code -> KEY_UP -> empty Field
An example (nasty code):
Message.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.ENTER)
{
// Your code...
}
});
Message.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.ENTER)
{
Message.text = "";
}
});
If you are able to enter a carriage return, it means the TextField is multiline, isn't?
Have you tried to empty your input text in a KeyboardEvent.KEY_UP event listener callback function?
Are you hitting enter with text field in focus? In that case, it might be that onKeyDown is called before the text field's value is updated by the keyboard action. You set the textfield to empty string in the onKeyDown, and then flash adds a new line to it.
Add a text input event listener to the text field and add trace statements to both event handlers to know the order of events.
If you are in Flash authoring mode (in the IDE), you need to uncheck Control -> Disable Keyboard Shortcuts while testing. Also try making a "cleanup" handler for KEY_UP.
inputfield.addEventListener(Event.CHANGE, onChange);
private function onChange(e:Event):void {
if ( inputfield.text.charCodeAt(inputfield.text.length - 1) == 13 ) {
inputfield.text = inputfield.text.substr(0, inputfield.text.length - 1);
}
}
I know it is a very old question, still thought of sharing my solution. I disabled multiline feature of textbox in fla file. After that I don't get any carriage return in textbox.
This does seem to be some kind of bug - I get it too. If you just set textField.text = "" in your constructor (or where-ever) it seems to resolve the problem.
I am working on an ASP.NET web application that is required to bring up a popup on a roolover. I am using the "OnMouseOver" event and it works as expected. The problem is that the event is on a "hair trigger"; even a casual passage of the mouse over the control brings up the popup (which then must be manually dismissed). I want to add a delay so that a rapid pass over the control in question does not trigger the event. Is there a way to set such a delay or is there a different event that I could use to get the same "trigger event on a slow rollover"?
One solution that comes to mind, there may be better ways though:
Make the onmouseover call the function via a setTimeout delay
Inside the function, check the mouse is actually over that element.
You could also use an onmouseout to clear the setTimeout, but then you'd have to store a reference to the timer in a global variable to get at it again.
What I ended up doing is as follows (oRow is a table row but it could be any control):
function ItemMouseOver(oRow, "parameters for the popup")
{
oRow.showTimer = window.setTimeout(function()
{
alert('popup');
}, 1000);
}
function ItemMouseOut(oRow)
{
if (oRow.showTimer)
window.clearTimeout(oRow.showTimer);
In the ASP.NET grid view RowDataBound event: I added the following code:
protected void ReportGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && (
e.Row.RowState == DataControlRowState.Normal
|| e.Row.RowState == DataControlRowState.Alternate))
{
// get the input values for the popup for the row (stuff deleted)
e.Row.Attributes["onmouseover"] = "javascript:ItemMouseOver(this,
"parameters for the popup");";
e.Row.Attributes["onmouseout"] = "javascript:ItemMouseOut(this);";
}
}
It works just fine. Thanks.