Actionscript how to get name of instance using getChildByName - actionscript-3

Okay so I have a MovieClip called sC and need to write a code where, if you click the button (sC) then sC will dissapear. The function needs to work for multiple buttons. What I tried was
sC.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void {
var self;
self = MovieClip(getChildByName(event.target.name));
self.visible=false;
Now when I try this code, it gives me an error when I click sC. It says "cannot access a property or method of a null object reference.". when I try to trace(self) it outputs "null". Is there a way where I can get the name of the instance of the object which is using the clicKHandler function and then make it's visibilty equal to false (visible=false)?
Note that when I trace(event.target.name) it says "instance127".

In your code, the variable self resolves to your movieClip's name, but not the complete path to where it exists. Try setting it up like below, where target is the button that was clicked:
sC.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void
{
event.target.visible = false;
}

Related

ActionScript 3 - use [brackets] instead of getChildByName

I have a MovieClip inside library, linkaged to MyObject and it contains a textField.
I don't know how I can access this textField without using the getChildByName method.
Apparently, the 3rd section works when object is on stage (without using addChild). But when using addChild I think there has to be some kind of casting; which I don't know how.
var childElement: MyObject = new MyObject();
childElement.name = "theChildElement";
container.addChild(childElement);
btn.addEventListener(MouseEvent.CLICK, changeText);
function changeText(event: MouseEvent): void
{
var targetBox:MovieClip = container.getChildByName(childElement.name) as MovieClip;
targetBox.textField.text = "hello"; // THIS WORKS
// This works too:
// MovieClip(container.getChildByName("theChildElement"))["textField"].text = "hello"; // THIS WORKS TOO.
// THIS DOESN'T WORK. why?
// container["theChildElement"]["textField"].text = "hello";
}
As confusing as it may seem, instance name, and name are not the same. From your code you should always be able to get to your MC by it's variable name. To get your last like to work you could just use this.
childElement["textField"].text = "hello";
There is a difference between Symbols created by the Flash IDE, which aggregate other DisplayObjects and programmatically created DisplayObjects.
When a DisplayObject is created in the Flash IDE, it's instance name can be used to resolve the instance as a property - which means it can be accessed via []. The [] can be used to access properties or keys of dynamic declared classes - like MovieClip. This necessary because you'll most likely down cast to MovieClip instead of using the symbol class created by Flash. That is not possible when simply using addChild, addChildAt or setChildAt from the DisplayObjectContainer API.
It is always the save way to access it via getChildByNameand check for null because otherwise your app, website or whatever is doomed for 1009 errors as soon as someone is changing the symbols.
I'd create a bunch of helper methods, like
// not tested
function getChildIn(parent:DisplayObjectContainer, names:Array):DisplayObject {
var child:DisplayObject, name:String;
while (names.length > 0) {
name = names.shift();
child = parent.getChildByName(name);
if (!child) {
// log it
return null;
}
if (names.length == 0) {
return child;
}
}
// log it
return null;
}
function getTextFieldIn(parent:DisplayObjectContainer, names:Array):TextField {
return getChildIn(parent, names) as TextField;
}
function getMovieClipIn(parent:DisplayObjectContainer, names:Array):MovieClip {
return getChildIn(parent, names) as MovieClip;
}
Your third method doesn't work because you are trying to call the ChildElement by it's name
without using getChildByName method. On the other hand, you shouldn't call your textField textField, because that's already an actionScript property.
Your should rather call it 'displayText' for example.
For a textField called 'displayText' contained in childElement :
function changeText(event:MouseEvent): void
{
childElement.displayText.text = "hello";
}

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.

AS3 Removechild Addchild issue/error

I have been looking for an answer for hours:
My program:
Step I) When I click on a button, it displays a bitmap through addchild;
Step II) When I click on another button, it should remove the bitmap through removechild;
Step I) works perfectly but step II) doesn't work.
You'll find below some parts of my code:
First, I declare:
public var ajoutcarte4:MovieClip;
Secondly, In the main function I wrote:
var ajoutcarte4:Bitmap = new Bitmap();
Then, in a sub function triggered by the first button, I add the Bitmap to the stage (fl_bitmap is a function returning a Bitmap item):
ajoutcarte4 = fl_bitmap(couleur4+figure4);
ajoutcarte4.x=445;
ajoutcarte4.y=370;
addChild(ajoutcarte4);
So far so good but when I want to remove the child through another sub function triggered by a second button:
removeChild(ajoutcarte4);
It doesn't work because ajoutecarte4 is apparently null... Error 2007 when i get red of my condition...
change this
public var ajoutcarte4:MovieClip;
to
public var ajoutcarte4:Bitmap;
Then take out this line completely
var ajoutcarte4:Bitmap = new Bitmap();
And lastely
// add this like with this code
ajoutcarte4 = new bitMap()
ajoutcarte4 = fl_bitmap(couleur4+figure4);
ajoutcarte4.x=445;
ajoutcarte4.y=370;
addChild(ajoutcarte4);
You've declared a field ajoutcarte4 of type MovieClip, but then in your function, you declare a local variable ajoutcarte4 of type Bitmap, which is then added to the stage.
In the second function, you try to remove the field MovieClip, which has never been instantiated - and thus produces the error.
Change your declaration to this:
public var ajoutcarte4:Bitmap;
and call:
ajoutcarte4 = new Bitmap();
(without the var). Then it all should work correctly.

Remove dynamically added MovieClip using removeChild (undefined property error)

I am trying to remove a Movie Clip I created dynamically, when exporting I get the error
1120: Access of undefined property player_mc
function addplayer(id:String):MovieClip {
var mcObj:Object=null;
mcObj=getDefinitionByName(id.toString());
return (new mcObj()) as MovieClip;
}
// this creates the mc
function startplayer():void {
var player_mc:MovieClip = addplayer("s"+station.value);
addChild(player_mc)
}
// this is supposed to remove it
function stopplayer():void {
//the following line causes the error
removeChild(player_mc);
}
As you can see I am using addChild for a Movie Clip in my library, this can be library items with the class name s1, s2, s3...
I tried using removechild(getchildbyname(?????)); with no success. how do I simply remove a Movie Clip that does not exist at export?
if you don't want to declare player_mc as a global variable and if it's always the last child added you may use removeChildAt(numChildren - 1)
Try to declare player_mc as "global variable" on top of your code and not inside the function startplayer(). Than it should be accessible inside stoporch()
var player_mc:MovieClip;
function addplayer(id:String):MovieClip {
var mcObj:Object=null;
mcObj=getDefinitionByName(id.toString());
return (new mcObj()) as MovieClip;
}
//this creates the mc
function startplayer():void {
player_mc = addplayer("s"+station.value);
addChild(player_mc)
}
//this is supposed to remove it
function stoporch():void {
//the following line causes the error
removeChild(player_mc);
}
Your stoporch function is referencing a variable player_mc that is not in scope. It was defined as a local in startplayer.
You either need to save the reference somewhere that stoporch can see it, or set the name property when you add it, and then use getChildByName when you remove it.
your player_mc variable is defined locally, meaning it will disappear when the function startplayer() is done.
You can create a class variable outside of the functions:
private var _player_mc : MovieClip;
and create it like this within your function:
_player_mc = addplayer("s"+station.value);
to remove it, simply use:
removeChild(_player_mc);
A few options exist. Like others stated, creating the variable at class level would work. Another way would be to assign a name to the clip after it is made.
function startplayer():void {
player_mc = addplayer("s"+station.value);
player_mc.name = "playerMC";
addChild(player_mc)
removeChild(this.getChildByName("playerMC"));
}

ActionScript 3 name property is not returning the right name...?

I experienced a problem with the name property in as3, I created this "dot" movieclip and I exported to a class,
then I anonymously created a bunch of dots using a loop. I assigned numbers as name to each dots
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
dotContainer.addChild(d]);
}
}
so far so good, I checked that if I trace the name here, I will get the number I want.
However, it's not giving me the numbers if I trace it in other functions.
I added all of my dots to "dotContainer", and if I click on one of the dots, it will call this function
private function callFullSub(e:MouseEvent):void
{
var full_loader:Loader = new Loader();
var temp:XMLList = subImages[sub];
var full_url = temp[e.target.name].#IMG;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);
}
e.target.name is suppose to be numbers like 1 or 2, but it's giving me "instance66" "instance70" and I
have no idea why. Because I did the same thing with loaders before and it totally worked.
Any ideas? Thanks.
christine
The e.target returns the inner most object clicked on, this could be a TextField, another MovieClip or posibly a shape (I'm not 100% of the last one) inside the "Dot".
To prevent this you could try to set the mouseChildren property to false on the Dot's when you add them. This should insure that nothing inside the dots can dispatch the click event, and thus the Dot's should do it.
Perhaps you could also in the event handler verify the target type with code like this:
private function callFullSub(e:MouseEvent):void
{
if(!e.target is Dot)
throw new Error("target in callFullSub is not Dot but: " + e.target.toString());
//The rest of you code here
}
The answer is [e.currentTarget.name] I perform this all the time!
Should return "Dot1" "Dot2", etc.
If the value you wish to return is a number or other data type other than a string (name of object) use [e.currentTarget.name.substr(3,1).toString()]
Should return 1, 2, etc.
Navee
I tried to reproduce your problem first with Flex using runtime created movieClips and then with Flash using Dot movieClip symbols exported for ActionScript. Neither application exhibited the problem.
You may already know names like "instance66" "instance70" are default enumerated instance names. So, whatever is dispatching the MouseEvent is NOT the dot instance. Perhaps you are unintentionally assigning callFullSub to the wrong targets, maybe your containers? Try assigning it to dot instance right after you create them, like this:
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
d.addEventListener(MouseEvent.CLICK, callFullSub);
dotContainer.addChild(d]);
}
}
Be sure to temporarily comment out your original assignment.
Try this might work,..
d.name = i.toString();
You have not shown enough of your code for me to be able to give you a DEFINATE answer, I will however say this.
//After you create each loader you need to set its mouseEnabled
//property to false if you do not want it to be the target of
//Mouse Events, which may be superseding the actual intended target;
var full_loader:Loader = new Loader();
full_loader.mouseEnabled = false;
//Also you could name the loaders and see if what comes back when you click is the same.
ALSO! Add this to your Mouse Event handler for CLICK or MOUSE_DOWN:
trace(e.target is Loader); //If traces true you have an answer
I believe that the mouse events are being dispatched by the Loaders.
please provide more of your code, the code where the Loader.contentLoaderInfo's COMPLETE handler fires. I assume this is where you adding the loaders to the display list as I cannot see that now.