views:

3078

answers:

3

Is it possible to get a list of all instances with a name in a flash movie using actionscript 2. Like an array containing all named text areas, or all movieClip instances etc. I would like to get this so the designer can add or remove text areas etc. and the actionscript can dynamically find these and get the texts from a separate datasource.

I guess what I want is something like a DOM tree or even better something like how getElementByName() works in JavaScript. And allso get the string value of the instance name so I can find it's text value in an xml.

Let's say the designer add a new text area with the name "copyright" and my code should (without having to change the script) find the data with the id "copyright" in an XML file if it is there, and add the value to the text area.

A: 

It's been a while since I did any AS2 coding but perhaps you could use a combination of MovieClip.getInstanceAtDepth() and this.getNextHighestDepth() to find the highest depth in your movie then trace back through each lower depth until you find a getInstanceAtDepth() that corresponds to the clip you are looking to populate with new data.

I also noticed this example code in the AS2 documentation.

The following code traces the depth of all movie clip instances on the Stage:

for (var i in this) {
    if (typeof (this[i]) == "movieclip") {
    trace("movie clip '"+this[i]._name+"' is at depth "+this[i].getDepth());
    }
}

PS: I know you probably don't want to hear this but in AS3 it's a doddle as you can just iterate through this.children!

defmeta
Elements placed at author-time are assigned negative depths, and there's no way to get the minimum depth. So to be sure of iterating over all content, you'd have to go from getNextHighestDepth() down to -MAXINT.
fenomas
I've managed to convert most of my code to AS3, would you care to explain how to do this in AS3?
Stein G. Strindhaug
+1  A: 

Short answer: there's no "built-in" way to do this. You could try to scrounge up functionality similar to getElementByName(), but it would require starting at _root and spidering through your content - and strictly speaking a movie clip starts out with references to its children but they could be deleted at runtime, so this could fail.

With that said, this is a common problem and there are many approaches to it. One thing you might find more useful is to create a custom component attached to a custom class - say, "TextPlaceholder", and have your designer put copies of that where they want dynamic text. Then at runtime, this component could examine its _name property, or other custom component parameters, and based on those it could create a text field of the appropriate size, content, and so on. That's just one way of approaching it.

fenomas
+1  A: 

@Stein Gauslaa Strindhaug

This is pretty rough, but it should do the trick!

private function traceAllChildren(rootContainer:DisplayObjectContainer):void {
 for(var i=0; i < rootContainer.numChildren; i++) {
  var item:* = rootContainer.getChildAt(i);
  try {
   traceAllChildren(item);
  } catch (e:Error) {
   trace(e.toString());
  }
  trace(item.toString());
  // This is the block where you can affect
  // an 'item' depending on it's type, name, etc..
  // eg: 
  //  if (item.toString() == '[object TextField]') {
  //   item.text = "The text I want to insert";
  //  }
  // or
  //  if (item.name == myTextFieldNameVar) {
  //   item.text = "The text I want to insert";
  //  }
 }
}

Then call it like so: traceAllChildren(this) or traceAllChildren(myParentMovieClip).

I hope this helps, good luck!

defmeta
Thanks! It works nicely. Maybe a bit "dirty" to try parse all items, but I haven't noticed any slowness.
Stein G. Strindhaug