AS3 TextField - unwanted carriage return when setting value to "" - actionscript-3

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.

Related

Why doesn't stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, true) work?

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;
}
}

Rich Editable Text not dispatching Enter key event

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;

transform double click on Z to double click on mouse

When I click 2 times on the touch "z" (keycode 90) on my keyboard, my item is removed.
timer=new Timer(500, 1);
stageRef.addEventListener(KeyboardEvent.KEY_UP, removeDraggedItem);
private function removeDraggedItem(e:KeyboardEvent){
if(timer.running==true)
{
if(e.keyCode==90)
{
stageRef.removeEventListener(MouseEvent.MOUSE_MOVE, dragItem);
stageRef.removeEventListener(Event.ENTER_FRAME, itemHitTest);
draggedItem.removeEventListener(MouseEvent.MOUSE_DOWN, itemClick);
stageRef.removeChild(draggedItem);
toolbar.useText.text = "";
if (stageRef.contains(this))
stageRef.removeChild(this);
Mouse.show();
Engine.playerControl = true;
}
}
else if(e.keyCode==90)
{
timer.start();
}
}
I'd like to change it and when we click 2 times with the mouse the item is removed but I can't figure out how to do it... if mouseDown = true ? it does'nt seem to work...
EDIT :
Ok I've tried to change (e.keyCode==90) by (e.buttonDown). No errors but nothings is happening when I double click...any idea why ?
Your code is only listening for a KEY_UP event: stageRef.addEventListener(KeyboardEvent.KEY_UP, removeDraggedItem);. You should add a KEY_DOWN event as well and then use the KEY_DOWN event in conjunction with the KEY_UP event to check for a double click. The code to add a KEY_DOWN event is stageRef.addEventListener(KeyboardEvent.KEY_DOWN, functionName);.
On another note if your trying to use MouseEvent.DOUBLE_CLICK you have to enable double click for the object you wish to double click. Oh and definitely include flash.events.MouseEvent
object.doubleClickEnabled = true;
object.addEventListener(MouseEvent.DOUBLE_CLICK, functionName);
Also I noticed in your removeDraggedItem function, you start a timer if the keycode equals 90. Then the next time a KEY_UP event is thrown you check if the timer is running and if so you remove a lot of event listeners and objects. You never stop the timer or reset the timer or remove the timer, I was just wondering if that was intentional?

How to add event listeners to the numeric stepper's text box?

I have a numeric stepper and I want to add an event listener to its text box:
use namespace mx_internal;
durationStepper.inputField.addEventListener(Event.CHANGE,durationStepperTextInputChanged);
private function durationStepperTextInputChanged(event:Event):void
{
use namespace mx_internal;
trace(durationStepper.inputField.text);
}
However, the event function does not execute! I put a break point there and it does not reach it! What am I missing here? Thanks.
The problem is that the developer has stopped Change event from bubbling up. You can find it if you go to the source file of the NumericStepper. Here are two functions, which prevent you from getting the event.
override protected function createChildren():void
{
super.createChildren();
if (!inputField)
{
inputField = new TextInput();
//some code
//some code
inputField.addEventListener(Event.CHANGE, inputField_changeHandler);
addChild(inputField);
}
}
private function inputField_changeHandler(event:Event):void
{
// Stop the event from bubbling up.
event.stopImmediatePropagation();
var inputValue:Number = Number(inputField.text);
if ((inputValue != value &&
(Math.abs(inputValue - value) >= 0.000001 || isNaN(inputValue))) ||
inputField.text == "")
{
_value = checkValidValue(inputValue);
}
}
As you can see the second function has
event.stopImmediatePropagation();
In this case you have two options: either you should find another way of implementing your logic, or you can copy the source code of the component and eliminate this code line.
It would be fine to override the function, but it is private.
You can read about this common problem here
I have tried to choose the second way. It works perfectly! It is not only the *.as file, but some others, which are used in it.
You can download the component here.

Catch enter press in flash block on webpage

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.