Copy link to clipboard
Copied
This is probably easy stuff for most of you guys but have tried to have this working for the past hour and it's not working.
I basicly have made my own button which is a movieclip. Inside the movieclip on the normal/roll off state i've put a dynamic textfieldwith instance name "textbtn"
my button is supposed to span 2 frames on my mainstage, thought is need to say something different in each frame.
Sofar I have this inside the movieclip on Frame 1:
textbtn.text = MovieClip(parent).buttonText;
on my mainstage in frame1 I have:
back_btn.addEventListener(MouseEvent.MOUSE_OVER, buttonRollOver);
back_btn.addEventListener(MouseEvent.MOUSE_OUT, buttonRollOut);
back_btn.addEventListener(MouseEvent.CLICK, buttonClick);
function buttonRollOut(event:MouseEvent):void{
back_btn.gotoAndStop("off");
}
function buttonRollOver(event:MouseEvent):void{
back_btn.gotoAndStop("over");
}
function buttonClick(event:MouseEvent):void{
back_btn.gotoAndStop("click");
gotoAndStop("frontpage2");
}
var buttonText = "this is frame1";
on my mainstage in frame2 I have:
buttonText = "this is frame2";
I think you're unnecessarily complexifying things.
One good practice is not to litter the timeline inside movieclips with code. When you want to go find some code to adjust something you may have to traverse movieclips several levels deep to get at the code in some frame. It becomes unweildly very quickly.
If you want to use the timeline, I would register the event listeners and also set the text of the button from the root timeline. I also would not use "frame labels" as they're very antiquated
...Copy link to clipboard
Copied
sorry on my mainstage frame2 I have the following:
back_btn.addEventListener(MouseEvent.MOUSE_OVER, buttonRollOver2);
back_btn.addEventListener(MouseEvent.MOUSE_OUT, buttonRollOut2);
back_btn.addEventListener(MouseEvent.CLICK, buttonClick2);
function buttonRollOut2(event:MouseEvent):void{
back_btn.gotoAndStop("off");
}
function buttonRollOver2(event:MouseEvent):void{
back_btn.gotoAndStop("over");
}
function buttonClick2(event:MouseEvent):void{
back_btn.gotoAndStop("click");
gotoAndStop("frontpage2");
}
buttonText = "this is frame2";
Copy link to clipboard
Copied
you'll need to execute:
textbtn.text = MovieClip(parent).buttonText;
each time you want to update your textfield's text property.
Copy link to clipboard
Copied
I Did this instead
back_btn.addEventListener(MouseEvent.MOUSE_OVER, buttonRollOver);
back_btn.addEventListener(MouseEvent.MOUSE_OUT, buttonRollOut);
back_btn.addEventListener(MouseEvent.CLICK, buttonClick);
function buttonRollOut(event:MouseEvent):void{
back_btn.gotoAndStop("off");
var buttonText = "this is frame1";
}
function buttonRollOver(event:MouseEvent):void{
back_btn.gotoAndStop("over");
}
function buttonClick(event:MouseEvent):void{
back_btn.gotoAndStop("click");
gotoAndStop("frontpage2");
}
But gives me an error:
TypeError: Error #2007: Parameter text must be non-null.
at flash.text::TextField/set text()
at having2galleriestesttext_fla::namebutton_17/frame1()[having2galleriestesttext_fla.namebutton_17::frame1:5]
at flash.display::MovieClip/gotoAndStop()
at having2galleriestesttext_fla::MainTimeline/buttonRollOut()[having2galleriestesttext_fla.MainTimeline::frame3:24]
frame 1 line 5 is inside my movie clip button.
textbtn.text = MovieClip(parent).buttonText;
And Frame 3:24 is my inside my "buttonRollOut" function:
back_btn.gotoAndStop("off");
Copy link to clipboard
Copied
I think you're unnecessarily complexifying things.
One good practice is not to litter the timeline inside movieclips with code. When you want to go find some code to adjust something you may have to traverse movieclips several levels deep to get at the code in some frame. It becomes unweildly very quickly.
If you want to use the timeline, I would register the event listeners and also set the text of the button from the root timeline. I also would not use "frame labels" as they're very antiquated although usable.
To make your buttons I would make a movieclip (setting the base class of the clip to flash.display.Sprite for optimization) and include 3 layers. layer 1 background, layer 2 roll, layer 3 text. I don't see any "on" state mentioned in your code so I left that out. The roll or 'selected' and 'textfield' layers should have instance names so you can access them. For instance I'd name the selected state graphic to selected_mc and the TextField to text_txt.
If your button was named as you said back_btn then the code would look like this, remembering that the event passes a target property:
back_btn.addEventListener(MouseEvent.MOUSE_OVER, buttonRollOver);
back_btn.addEventListener(MouseEvent.MOUSE_OUT, buttonRollOut);
back_btn.addEventListener(MouseEvent.CLICK, buttonClick);
Sprite(back_btn.getChildByName('selected_mc')).visible = false; // make sure the initial selected state is invisible
function buttonRollOut(event:MouseEvent):void{
Sprite(Sprite(event.currentTarget).getChildByName('selected_mc')).visible = false;
TextField(Sprite(event.currentTarget).getChildByName('text_txt')).text = 'roll off'; // change to the roll off text
}
function buttonRollOver(event:MouseEvent):void{
Sprite(Sprite(event.currentTarget).getChildByName('selected_mc')).visible = true;
TextField(Sprite(event.currentTarget).getChildByName('text_txt')).text = 'roll on'; // change to the roll on text
}
function buttonClick(event:MouseEvent):void{
Sprite(Sprite(event.currentTarget).getChildByName('selected_mc')).visible = true;
TextField(Sprite(event.currentTarget).getChildByName('text_txt')).text = 'selected text'; // change to the selected text
gotoAndStop("frontpage2");
}
TextField(back_btn.getChildByName('text_txt')).text = 'start text'; // change to the starting text of the button
The display list returns DisplayObject and DisplayObjectContainer so you always need to wrap things with the 'type' they are to access them properly. That's why I have Sprite() and TextField() wrapped around specific things. Doing that gives you access to their settings.
Copy link to clipboard
Copied
I mean: this is just beautiful...
no more error messages, just 2 questions:
in my second gallery I've done the following:
back_btn.addEventListener(MouseEvent.MOUSE_OVER, buttonRollOver2);
back_btn.addEventListener(MouseEvent.MOUSE_OUT, buttonRollOut2);
back_btn.addEventListener(MouseEvent.CLICK, buttonClick2);
Sprite(back_btn.getChildByName('selected_mc')).visible = false; // make sure the initial selected state is invisible
function buttonRollOut2(event:MouseEvent):void{
Sprite(Sprite(event.currentTarget).getChildByName('selected_mc')).visible = false;
TextField(Sprite(event.currentTarget).getChildByName('text_txt')).text = 'gallery1'; // change to the roll off text
}
function buttonRollOver2(event:MouseEvent):void{
Sprite(Sprite(event.currentTarget).getChildByName('selected_mc')).visible = true;
TextField(Sprite(event.currentTarget).getChildByName('text_txt')).text = 'back'; // change to the roll on text
}
function buttonClick2(event:MouseEvent):void{
Sprite(Sprite(event.currentTarget).getChildByName('selected_mc')).visible = true;
TextField(Sprite(event.currentTarget).getChildByName('text_txt')).text = 'back'; // change to the selected text
gotoAndStop("frontpage2");
}
TextField(back_btn.getChildByName('text_txt')).text = 'gallery1'; // change to the starting text of the button
but the button first shows when the mouse rolls over..?
In my dynamic textfield aka. "text_txt" only "gallery" and the letter "A" appears - I've tried to make the text field bigger, but still the samme, is there somewhere I have forgot something..?
Copy link to clipboard
Copied
forgot to embed font...
Copy link to clipboard
Copied
thank you so much - it works perfect
Copy link to clipboard
Copied
I'm not quite sure I follow but are you saying that you don't want the button to show up but it is? The roll is setting the visible property on the selected state so that will fire off every time you roll over it.
If the buttons are not supposed to show you should just initially set the .visible property of the entire button to false to assure it won't show up. You should also set the mouseEnabled property to false (and perhaps useHandCursor to false) so the user can't click it until you desire them to.
edit:
Ah ok, you're welcome.
Copy link to clipboard
Copied
Hi Sinious,
similar challenge here...
I have a dynamic text field which currently works fine on the stage.
(see code below).
When I covert this field to a symbol movie clip,
I can't seem to find the correct AS3 code to pass the text into the movie clip.
I tried this without success;
dynamic test field name = a_field
movie clip instance name = a_mc
AS3 code: _root(a_mc.a_field);
~ ~
below is the current code which works fine prior to converting the dynamic text field to a movie clip;
CS5.5 Flash AS3
import flash.netURLLoader;
var xmlData:XML = new XML();
var the URL_ur:URLRequest = new URLRequest("fieldinput.xml");
var loader_ur:URLLoader = new URLLoader(theURL_ur);
loader_ur.addEventListener("complete", fileLoaded);
function fileLoaded(e,Event):void
{
xmlData = XML(loader_ur.data);
a_field.text = xmlData.a_text;
}
side note.... within these forums, is there a way to insert one's code rather than retyping?
Thanks in advance for your time and guidance.
D-
Copy link to clipboard
Copied
How you keep your references is completely up to you. If you never made a reference to the textfield or the movieclip (as a class variable or directly in a timeline script or such) then you'll have trouble accessing it.
This is AS2, it no longer works in as3: _root
I presume you're doing this in a frame script. I also presume you put a_mc and a_field in a frame manually by dragging it out of the library and onto the timeline.
First thing to do is make sure you have an instance name specified. You mtnioned you set up a_mc and a_field. Those need to be instance names and not the name of them in the library. Whatever you name them in the library is meaningless. Once you drag them into your timeline, click it and look at your properties panel. The first textbox is the instance name. Those must be set properly for this to work.
Here, I just keep re-using this screenshot I made to point out instance name which has nothing to do with your project but you get the idea:
Make absolutely sure you gave them names.
Then you need to always "type cast" which is a pain in the ass but is necessary. So for example you added correct instance names. You can literally:
TextField(a_mc.getChildByName('a_field')).text = XML(loader_ur.data).toString();
Copy link to clipboard
Copied
Thanks for your help.
I inserted your script within the "function" noted in Post #9... with a host of complier errors.
While posting it out side the "function" with both complier & output errors.....
Does the MovieClip " a_mc " have to be declared first?
a_mc = new MovieClip();
var a_mc:MovieClip;
..... I tried this with only further errors......
~ ~ ~
The script in Post #9 works fine until I change the textfield to Dynamic...
If there is more AS3 required I would welcome your ideas.....
(all the code thus far is what is in Post #9 )
At a loss....
Thanks again
D-
Copy link to clipboard
Copied
If you do not put something on the timeline with the "Instance Name" (refer to graphic) as a_mc, then yes it will need to be created before you can use it. Otherwise no, you can directly use it if you put it on the timline. e.g. you clicked in a frame, clicked on the text tool, set it to dynamic text and had drawn a text box. Afterwards you named the text box instance something. You can then use that instance name directly in actionscript code.
However you did say a_mc and referred to it as a movieclip. So if that movieclip contained a dynamic text field, you'd need to go in a_mc and make sure the textfield had an instance name as well.
So lets say you have a movieclip on your timeline with the INSTANCE NAME of a_mc. Lets say inside that clip you had a textfield with the INSTANCE NAME of a_field. You could do this to dump the XML into it:
function fileLoaded(e:Event):void { TextField(a_mc.getChildByName('a_field')).text = e.target.data; }
And you can just paste code in here really, although sometimes it comes out as tables and other weird stuff. Most of us actualy use the "HTML" button in the upper right and add in something like <pre> or <blockquote> or other tags to help make the code easier to read.
Do note the reason I put TextField() around the code above is because any time you request to get a child by its instance name (getChildByName()) it returns a generic "DisplayObject". It's really annoying that the method doesn't sense the original type of the object it returns and generically returns a "DisplayObject" but that is what it does. So by putting TextField() around it I "cast" it back into what I know it should be, a TextField class. Therefore the .text() method will be available. Just a side note...
Copy link to clipboard
Copied
Sinious,
First of all, I greatly appreciate all the details and theory behind how & why the code works.
You coach the way I learn.. Thanks !!
Yes, I do have a Movie clip on the timeline (instance; a_mc) and within it, a dynamic text field (instance: a_field).
Before I test the script, I would welcome a bit of clarity;
At the end of your script above, you reference e.target.data.
With my current external text source the XML file (fieldinput.xml), will your script access this
exteranal file or do I use loader_ur.data as noted in my original "function fileLoaded..." in post #9 ?
Thanks again for your time and assistance.
D-
Copy link to clipboard
Copied
The function fileLoaded is called by your XML loader telling it that it successfully parsed the XML. Once that happens, all the data in the XML is included in the event, which has the variable name of 'e'. So e.target refers directly to the loader that loaded the XML in the first place. So it's exactly like saying loader_ur.data to say e.target.data. You don't really need to keep a reference to loader_ur because the data is sent in the event.
This is typically why people use the e.target.data approach. You create a loader in the middle of a function. You know at the end of that functions life the variable is garbage collected. However until the listener fires off, it still exists. Once the listener fires off after successfully loading the document people don't typically have a global variable (like loader_ur) to reference at all. They just refer to e.target to access it. So they access the loaders XML using e.target.data. After that the loader is removed in the next garbage collection sweep. You never really needed to keep loader_ur around at all. It just takes up extra memory.
Copy link to clipboard
Copied
Great.....
again, this helps a lot with a thorough understanding.
I look forward to testing the script this evening...
Many thanks
D-
Copy link to clipboard
Copied
You're welcome and good luck
Copy link to clipboard
Copied
I you have a moment, I have one other challenge I am working on.
(see forum re: "FlashVars pass field text to SWF")
In this forum, I have been working with some great folks teaching
me how to interface a SWF (RMA) which has been loaded into a PDF.
Here, I am using an Acrobat form field to interface
with the "said" dynamic text field we've been working with above.
The last piece of my challenge is to get my AS3 script written
properly to receive the text data sent from the PDF.
If you are aware of any examples of this (PDF to SWF:RMA) project
both AcroJS and AS3 scripts I'd appreciate a link or two....
Thanks again
D-
Copy link to clipboard
Copied
I think I already posted in that link (I don't have the URL to atm). I mentioned to show the PDF in a StageWebView instance and then it was made clear there was some acrobat scripting syntax that I wasn't familiar with. There were links mentioned that deconstruct PDFs and let you access things inside them but displaying a PDF and accessing data from it at the same time is another level of difficulty. Most APIs either just let you display the PDF or let you read its guts and reconstruct it. Reconstructing is what you appear to want so I'd go that route. It's a lot of work but it lets you convert an input from a PDF into an actionscript input that looks identical (when styled to do so) so you can access the data that way.
Otherwise this is not at all someone new to actionscript should be approaching. It's not "easy".
Copy link to clipboard
Copied
Agreed,
A novice to AS3... it's been a steep learning curve.
Joel G. is planning on developing some examples soon...
he has been a great resource...
~~~
Back to your Lesson.... the Script worked perfect.....Thank you..
Planning ahead .... when you have a moment,
would you please explain how to code the same FLA with Multiple Dynamic text fields(which have respective MovieClips) ?
Further, how would the/my xml file / code change?
With the current coding above, say I add:
MovieClip instance: b_mc , with a Dynamic text field instance: b_field
Thanks in advance... again.
D-
Copy link to clipboard
Copied
Reading the PDF and reconstructing it is no simple task, that's for sure. When I say reconstruct I mean literally reading all the contents on a particular page and rebuilding that in flash using what flash has. Text in TextFields, images in Loaders, etc etc. Then all that content needs to be position. Inputs will need to be TextFields with the .type property set to be an input. It's a ton of work.
Perhaps you could utilize a PDF to SWF converter?
Have a look at this article below to see some useful information on PDFs and Flash:
Copy link to clipboard
Copied
Thank you Sinious,
I appreciate the PDF / Flash reference link.
Insightful tools...
~ ~
Thanks again for the script re: accessing a dynamic text within a MoiveClip.
D-
Copy link to clipboard
Copied
You're welcome and good luck
Copy link to clipboard
Copied
Hi Sinious,
Some good news,
I was able to contruct the Interfacing codes (AcroJS and AS3) to have a
PDF form TextField interface with a SWF (RMA).
The origianl script (above) works perfect with the assumption, the
SWF's dynamic TextField was interfacing with a XML file.
So with the SWF now interfacing with a PDF, will the AS3 code above still
pass the dynamic TExtField into the MovieClip?
My first few attampts have been unsuccessful.....
D-