AS3 set focus on specific component - actionscript-3

I have a form with several component: datagrid, textArea, text input...
For each component FocusIn Event is available.
var objTarget:String;
protected function memo_focusInHandler(event:FocusEvent):void
{
objTarget=event.currentTarget.id;
}
With memo_focusInHandler, I know which has focus.
My goal is to backup last focus objet, and re open Windows with focus on this object.
I try to do this:
objTarget.setfocus();
But it doesn't work. Could you help to found the best way to reach my goal.

String is not a display object, thus it can't be in focus. The representation of string on the stage is a TextField.
In as3 you can set focus to the desired target by using stage method:
stage.focus = myTarget;
Please see the corresponding documentation section: https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Stage.html#focus

There is no need (that you've shown) to work with the string id reference. It would much simpler (and slightly more efficient) to work directly with the object reference.
var objTarget:Object; // Object instead of type :String
protected function memo_focusInHandler(event:FocusEvent):void {
objTarget = event.currentTarget; //instead of the currentTarget's id property, assign the current target itself
}
Then, when you want to reset focus, you can do:
if(objTarget is TextInput || objTarget is TextArea){ //make sure it's a text input or text area first - optional but recommended if you don't like errors
objTarget.selectRange(objTarget.text.length, objTarget.text.length); //set cursor to the end
objTarget.setFocus(); //focus the text input/area
}

I found a solution:
this[objTarget].selectRange(this[objTarget].text.length, this[objTarget].text.length);
this[objTarget].setFocus();

Related

AS3 Have whatever I type into Text Input turn into a variable?

I'm fairly new to AS3 and I want to know how would I go about having whatever is typed into a Text Input to become a variable? For example, in a text input under name if I were to type in "Jeffrey" that would become a variable and I could then use that to display "Hello, Jeffrey" or something like that with whatever the name inputted is replaced with Jeffrey.
It's fairly simple to implement this. One way you could do this is have a keyboard event running while input is being made. Then assuming you have the textfield created and ready for input, you have a variable that stores the textfield text property. So you would create your variable:
private var inputText:String;
Next add your listener:
stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
Then create the listener function, and in that function set your variable to the textfield text. In this example let's assume your textfield is called myTextField:
private function onKeyDown( e:KeyboardEvent ):void {
textInput = myTextField.text;
}
Now you have a variable that is storing the textfield's text every time a key is pressed.
Whenever you are done with the input, remove the listener from the stage:
stage.removeEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
Now there is also an alternative way. You can attach a TEXT_INPUT event to the textfield and capture the input that way, like so:
myTextField.addEventListener( TextEvent.TEXT_INPUT, onInput );
public function onInput( e:TextEvent ):void {
inputString = myTextField.text;
}
There are two parts to this:
1: Define "something that is typed into a TextInput".
The reason for this is that each thing is typed in one keystroke at a time. This is important, because for the word "Jeffrey", you have several different things that get typed into there:
J
Je
Jef
Jeff
Jeffr
Jeffre
Jeffrey
You probably don't want all of those turned into variables, but ActionScript 3.0 will more-or-less think of those as all separate inputs. Somehow you have to distinguish "Jeffrey" from all the rest. Usually this is done by making the user click a Submit button or tab off the TextInput or something, but you'll have to decide.
2: Add a dictionary variable to your class and use the input as one of its keys:
private var myDict:Dictionary = new Dictionary();
Whenever the program decides that the user has finished typing something into the TextInput (like in a Submit button's click handler), just do this:
myDict[myTextInput.text] = new Object(); // or whatever value you want
So let's say the user entered the value "Jeffrey". Then you could come back later and access what is effectively a variable by that name:
myDict[myTextInput.text] = 5; // myTextInput.text == "Jeffrey"
.
.
.
trace(myDict["Jeffrey"]); // output is "5"
trace(myDict.Jeffrey); // output is "5"
trace(myDict[myTextInput.text]); // output is "5" if myTextInput.text is the same
Effectively rolling back an earlier edit, just go ahead and use a Dictionary, not an Object. If the user types in certain things like "12345", things will just go better if you use a Dictionary.

Removing an EventListener from an object decided via an Array

I am making a simple calculator for an assignment in my IT-Class. It has 3 textboxes where the user can add his numbers, and the boxes start with a "0" inside of them, to show that the user is supposed to write numbers here. What I wanna do, is have this zero go away as the user puts focus on the box.
Since I have 3 boxes, I wanted to make the EventListener call up a function that removes the text and the Eventlistener, instead of writing the same code 3 times.
Using an array containing the different textboxes I managed to call them up, and change the text as I wanted, but the EventListener isn't being removed, so the text the user writes in is being removed when they focus on the textbox again
///////////////////////////////////////////////////////////////////////////////////
//The Array containing all the TextFields
var textFieldArr:Array = new Array(txtNumber1,txtNumber2,txtNumber2)
function onFocus(i:int){
return function (evt:FocusEvent){
textFieldArr[i].text = "";
textFieldArr[i].removeEventListener(FocusEvent.FOCUS_IN, onFocus(i))
}
}
//Calls up the onFocus function and declares variable i
txtNumber1.addEventListener(FocusEvent.FOCUS_IN, onFocus(0));
txtNumber2.addEventListener(FocusEvent.FOCUS_IN, onFocus(1));
txtNumber3.addEventListener(FocusEvent.FOCUS_IN, onFocus(2));
///////////////////////////////////////////////////////////////////////////////
Your event listener isn't being removed, because when you call onFocus(i) within the removeEventListener param, you are being returned a new function, and not the function that was originally being triggered by the event. The other problem with your code is that 'i' does not exist in the listener function you have declared -- you need to use only the properties of evt to figure out which text field to target, and the correct event listener to remove.
The common/correct way to do this is to use a event-accepting function, and listen to each text field with it. You don't even need the array anymore unless you have some other use for it.
function onFocusIn(evt:FocusEvent):void{
trace("onFocusIn("+evt.target+")");
var focusedField:TextField = TextField(evt.target);
if(focusedField){
focusedField.text = "";
focusedField.removeEventListener(FocusEvent.FOCUS_IN, onFocusIn);
}
}
txtNumber1.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
txtNumber2.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
txtNumber3.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
Listener is not removed, because onFocus returns on each invocation new Function instance.
You might try use target property of FocusEvent class:
var textFieldArr:Array = new Array(txtNumber1,txtNumber2,txtNumber2)
function onFocus(evt:FocusEvent){
TextField(evt.target).text = "";
TextField(evt.target).removeEventListener(FocusEvent.FOCUS_IN, onFocus)
}
//Calls up the onFocus function and declares variable i
txtNumber1.addEventListener(FocusEvent.FOCUS_IN, onFocus);
txtNumber2.addEventListener(FocusEvent.FOCUS_IN, onFocus);
txtNumber3.addEventListener(FocusEvent.FOCUS_IN, onFocus);

Make Flex TextInput show no prompt on empty String

I am using a s:TextInput in Flex 4.5. It shows it's prompt text if the underlying text value is null or empty String. Does anybody know if I can make either don't show the prompt on empty String or even show a different prompt?
I already found a way by extending the TextInput class and overriding some of the methods but I am still hoping anyone here knows an easier way ;-)
Ok, so based on the comments, here it is:
You store the current prompt value in a private variable, like so:
private var _inputPrompt:String = "";
Then you create a getter, so the value is accessible from outside of this class:
public function get inputPrompt():String
{
return _inputPrompt;
}
Now you can bind inputPrompt anywhere you need it, however, the problem is the getter won't be recalled once the private value changes. You can fix this very easily: Create an update method, for example like so:
public function updateInputPrompt(value:String):void
{
_inputPrompt = value;
}
Ok, nothing fancy so far. I'm guessing this is the point where you are right now. In order to "force" the getter to be recalled, you have to bind it to an event, like so:
[Bindable(event="inputPromptUpdated")]
public function get inputPrompt():String
{
return _inputPrompt;
}
Finally, you can simply dispatch this event when the value is update (i.e. in the updateInputPrompt method):
public function updateInputPrompt(value:String):void
{
_inputPrompt = value;
dispatchEvent("inputPromptUpdated"); // For binding
}
This way, the getter will be recalled every time you dispatch that event.
Hope this helps. Have a great day, and a great weekend!

checking if child exists

Hello i have a function as following:
private function seatClickHandler(e:MouseEvent):void{
var check:Check = new Check();
if(e.target.contains(check)){
e.target.removeChild(seat);
}else{
e.target.addChild(check);
}
}
basicly i want to check if e.target contains a child called check. If it does i want e.target to remove the child, else i want to add the child. But the method i tried doesnt seem to work although i think this is the way to go. Any suggestions?
When you declare your Check object, Actionscript creates a reference code for that specific object.
So the first time your code is run, your Check object could be given a reference of #c0ecc29. Your if statement checks to see if #c0ecc29 is a child component of target. It won't be, so the Check object with reference #c0ecc29 is added to target.
The second time the clickHandler is called, a new instance of the Check object is created which will have a new reference id. Your target has the original Check object with the #c0ecc29 reference so it won't get removed.
The correct way to get this working depends on what target is (DataGrid, Group, etc.).
EDIT:
Based on your comments, I would try something like this. It checks to see if the Check object is a child of target and adds it if needed. Then when the Check object is clicked, it will toggle its visibility.
public var check:Check = new Check();
private function seatClickHandler(e:MouseEvent):void
{
if(!e.target.contains(check))
{
check.addEventListener(MouseEvent.CLICK, check_handleClick);
e.target.addChild(check);
}
}
protected function check_handleClick(event:MouseEvent):void
{
check.visible = !check.visible;
}
If you need to actually remove the Check object from target instead of just changing its visibility, you could try this:
public var check:Check = new Check();
private function seatClickHandler(e:MouseEvent):void
{
if(!e.target.contains(check))
{
e.target.addChild(check);
}
else
{
e.target.removeChild(check);
}
}
If the child is named 'check' then you should be able to use getChildByName(). See flash.display.DisplayObject.name
If you happen to have the child in memory, you can use getChildIndex()
check is a new object in the scope of that function, so it will not be a child of the event target.
What you want to do is declare check as a global variable (And also cast target as DisplayObjectContainer).
e.g.
private function seatClickHandler(e:MouseEvent):void{
if((e.target as DisplayObjectContainer).contains(check)){
(e.target as DisplayObjectContainer).removeChild(seat);
}else{
(e.target as DisplayObjectContainer).addChild(check);
}
}
However I'm not sure if this is exactly what you want to do (There can only be one check). A better approach would be to have a function (maybe toggleCheck) on the target, and have that display object responsible for rendering the check (And removing it)
This worked perfectly fine for me in my situation:
if(possibleChild.parent == holder)
holder.removeChild(possibleChild)
It may or may not be exactly what you're looking for.

ComboBox Bug in ActionScript

I was trying to filter a combo box dataprovider based on the values in the text boxes . When the contents of the dataprovider changes Combo box automatically calls change event method . Please find the sample code below.
Filter Utility Function:
private function filterLocations(event:FocusEvent):void {
locationsList1.filterFunction = filterUtility;
locationsList1.refresh();
}
public function filterUtility(item:Object):Boolean {
// pass back whether the location square foot is with in the range specified
if((item.SQUARE_FOOTAGE >= rangeText1.text) && (item.SQUARE_FOOTAGE rangeText2.text))
return item.SQUARE_FOOTAGE;
}
// THIS WOULD BE CALLED WHEN COMBO BOX SELECTION IS DONE
private function selectLocationsReports(event:ListEvent):void {
selectedItem =(event.currentTarget as ComboBox).selectedItem.LOCATION_ID;
}
When the DataProvider gets refreshed its automatically calls change method and was throwing Null Pointer function because its prematurely calling the above selectLocationsReports method and its throwing error.
Can somebody let me know how to stop the CHANGE event from propogation when the dataprovider is refreshed.
You can't stop a CHANGE event, just don't add an event listener unless you are prepared to get the event. I don't see where your event listener for Event.CHANGE is in the code above.
Just be sure that you don't addEventListener(Event.CHANGE, selectLocationsReports) until your ComboBox is ready for it.
The other thing to do (on top of Kekoa's response) is put an if statement in the event handler, and check to make sure the data is there before you begin working with it.
A handy syntax I use frequently for this is
if(dataprovidername) {
}