Freelancer behind 5 1/2 math and physics enthusiast Patrick has a knack for making seemingly simple things overly complicated. Perfect for a tutorial writer. Hello all and welcome to the third installment in the Actionscript for Flash 5 dummies series, Creating radio buttons. I know, I know, it's been a long time coming, but I think you'll find it was worth the wait.
If you're new to the series, I heartily recommend that you read the two first installments, Scrolling a text box I and II. While they're not necessary in order to finish this tutorial, it's still a good idea to read because this tutorial has in mind that you completed the first two tutorials.
As always, you can be reminded of further tutorials by sending a blank e-mail to [email:as_for_flash5_dummies-subscribe@yahoogroups.com] with "subscribe" in the subject line.
Without further ado, here's the movie we're going to make:
Now, I know what you're saying. Radio buttons, how, hum, boring. Why yes, in fact. However, they are some of the most basic and intuitive to use interactive elements. The important thing to remember is that almost anybody that will go to your site will know instinctively how to use them.
Not only is it easy for users to use radio buttons, but if you code your buttons right, they will also be extremely easy for you to use. That is, updating, or recreating such a thing will be as easy as editing a few lines of code, or copy and paste.
Okay, enough with the small talk, let's get it on already.
I know this will sound stupid, but let's start by analyzing how a radio button is made. Trust me, there are many elements which I'm sure you haven't thought of.
Well, first and foremost, a single radio button has two states: on and off. It also has a label, that is, a small blurb of text that sits there on the right and tells you what the button is for.
A radio button can be selected by clicking on it, but it can't be unchecked by clicking on it again; you have to select another option. And that's where the concept of dependency comes in: you can't have a radio button by itself. It doesn't make sense. The radio button must be part of something bigger, an option list, and it must be able to communicate with it.
So we'll start by creating a single radio button, which we'll put in relation to others later on. Create a new movie clip and name it "single radio button". Create two layers in it: states and label. In the first frame of the states layer, you should put a picture of an unclicked radio button, and in the second frame, the picture of it clicked. In my case, I simply used screenshots of radio buttons in different states, but you may use whatever you want.
Now in the first frame of the "label" layer of your movie clip, create a dynamic text box, about the length of 25 or so characters of text, and choose "label" as the variable name in the text options panel.
Your movie clip should now look like this:

Simple enough right? The first frame acts as the unselected radio button, and the second as the selected button. As you've probably guessed by now, we'll simply switch between these two frames in order to select and unselect our radio buttons.
Now that this is done, get out of that movie clip and go into your main timeline. Drag an instance of the "single radio button" and drop it into the first frame of your main timeline. Name it "radioButton0" in the instance properties window. That's it for the graphics part.
Wait a minute? That doesn't make sense, you say, I want more than one frigging radio button!!! Touché. The beauty of the script we're going to make is that it will be self-constructing: the script itself will make the radio buttons, not ourselves. So it will simply use this button as a template for all the others. It will even create text labels for each of them!
This will make updating your movie much easier, since you won't have to touch the graphics part. Instead, you'll just modify a few lines of code and the script will do all the dirty work for you. Meanwhile, you can peruse half-naked in your home drinking cheap tequila while your boss thinks you're doing work. That's right, better living through actionscript. Who would have thought?
Now, seriously folks, you will still have to do a little work. The important thing is, you'll only do it once.
As I've noted earlier, a single radio button can't do much by itself, but it must be able to communicate with a whole group of radio buttons. Most notably, it should be able to tell the whole group that it has been clicked on. So what we're going to do is create an interface that will allow us to do so.
Select radioButton0 in the main timeline, go into the object actions panel and add this script:
[as]onClipEvent(load){
this.stop();
this.myName = Number(this._name.substring(11, 12));
}
onClipEvent(mouseDown){
if(this.hitTest(_root._xmouse, _root._ymouse)){
_parent.reportClick(this.myName);
}
}
[/as]
All right, that's not too complicated, now is it. The first element in our script is the load clip event, which, as you remember, executes only once: when the clip is loaded.
The first line in this event tells the clip to stop, so that it won't continually toggle between its on and off states. The second is admittedly more complicated. I think this dialog will better illustrate the point of this line:
- Yo, hum, main clip?
- Yeah dude, what?
- I've like, been clicked on and stuff.
- Wait, who are you?
- Hum, I dunno dude
- Idiot...
As you can see, the clip must communicate with the whole group of radio buttons in order to tell it that it has been clicked. Of course, it must know it's own name in order to do so. Preferably, it should also know its "number", that is, the position of the radio button from the top of the radio button group.
So what the second line does here is that it first uses this._name, a property defined by default by Flash, in order to retrieve the name of the current clip. In this case, this would return "radioButton0". The important part of this string being the "0", we take a substring, or portion of the "radioButton0" string from the 11th to the 12th character; this will extract the last character, "0". This character is next converted to a number.
The rest of the script is contained within a mouseDown clip event, which is executed every time the mouse is clicked. The first line in this event should be familiar to you if you've followed the second tutorial; it checks whether the mouse was over the clip when it was clicked. If so, it triggers a function in the parent of this clip, the group of radio buttons, in order to report to it that it has been clicked, passing along with it its radio button number.
Simple enough, right? Now let's take a look at how we're going to handle multiple radio buttons.
All right, so we have a single radio button done and ready. Of course, a radio button can't exist by itself; it just doesn't make sense. It must be put in relation to other radio buttons in order to work properly.
Select the radioButton0 clip in the main timeline and press f8 in order to nest it into a parent movieclip. Name this clip "radioButtonGroup".
This clip will act as the parent of our radio buttons. Most of the work will be done by it. Its first duty will be to create a set of radio buttons from the template, and add captions to them.
Let's see how this translates into actionscript. Select the radioButtonGroup clip in the main timeline, and add this script to it:
[as]
onClipEvent(load){
labels = new Array();
labels[0] = "potato";
labels[1] = "potato";
labels[2] = "potato";
labels[3] = "Zimbabwe";
numButtons = labels.length;
vSpacing = 20;
for(i = 0; i < numButtons; i++){
if(i != 0){
radioButton0.duplicatemovieclip("radioButton" add i, i);
this["radioButton" add i]._y += i*vspacing;
}
this["radioButton" add i].label = labels[i];
}
}
[/as]
Let's examine this script line by line. The script is contained within a load clip event, which will only be executed once.
It starts off by defining an array named labels. This array will, as you've probably guessed, hold all of the labels for our buttons. labels[0] holds the label for our first radio button, labels[1] the label for our second radio button, and so on.
Next, the script defines the numButtons variable. Since there are as much radio buttons as there are labels, it makes sense to use the length property of the labels array in order to determine the total number of radio buttons.
The vSpacing variable holds the spacing, in pixels, between each of the radio button items. This will be useful to us when we place our buttons.
Now, for the meat of our script. As you remember, the single radio button we created acts as a template for all of our radio buttons. So we just need to duplicate it a set number of times, align the duplicates vertically, fill in the captions, and boom... we got ourselves some radio buttons.
So we start by defining a for loop that will be executed from 0 to the number of buttons - 1, for a grand total of numButtons times. Now, every time the loop is executed, it will first start off by duplicating our radioButton0 template. The duplicate will be named radioButtonX, where X is its number from the top, and placed on the Xth level.
When a movie clip is duplicated, it retains all of the properties from the original clip, including its position. Since we don't want our radio buttons to overlap, we'll simply move them an appropriate number of pixels vertically. For example, if a radio button is third from the top, then its "number" would be 2, and it would have to be moved 40 pixels vertically; more simply, number*vSpacing pixels.
Of course, since our template radio button, radioButton0, is already on the timeline and in its rightful place, we don't need to duplicate it or place it. Hence, we wrap these two last actions inside an if to make sure that we don't do so.
Finally, we fill the label text box with the appropriate label. That's it!
You might have noticed by now that we've been using this["radioButton" add i] to address our shiny new radio buttons. This is something called bracket syntax. Sometimes, we need to create variable or movieclip names dynamically, and bracket syntax is the answer to that problem.
What Flash does when it sees bracket syntax is that it evaluates what's inside the brackets as an expression. So if i is 2, this["radioButton" add i] becomes this["radioButton2"]. Next, it gets rid of the brackets and adds a dot before them, so this["radioButton2"] becomes this.radioButton2. Simple, now ain't it?
Before I move on, let me note that when you duplicate a movie clip, its attached actions are duplicated along with it. What this means is that like our template radio button, our duplicates will be able to know their own name and report their clicks to the parent movie clip. Hence, our clips will be self-aware and fully functional after being duplicated.
All right, we've got plenty of pretty radio buttons now, but the problem is, they don't do anything! Let's determine what our parent radio button group must be able to do.
First, it must be able to respond properly to the reportClick() function we defined earlier. This function must be able to select the clicked radio button, if it's not selected already.
We also need to be able to select a radio button by default. Finally, our parent clip should be able to tell us which radio button is selected.
Let's see how this all translates into actionscript. The old parts of the script are grayed out:
[as]onClipEvent(load){
labels = new Array();
labels[0] = "potato";
labels[1] = "potato";
labels[2] = "potato";
labels[3] = "Zimbabwe";
numButtons = labels.length;
vSpacing = 20;
default = 3;
for(i = 0; i < numButtons; i++){
if(i != 0){
radioButton0.duplicatemovieclip("radioButton" add i, i);
this["radioButton" add i]._y += i*vspacing;
}
this["radioButton" add i].label = labels[i];
}
select(default);
function reportClick(clicked){
if(clicked != selected){
select(clicked);
}
}
function select(clicked){
for(i = 0; i < numButtons; i++){
this["radioButton" add i].gotoAndStop(1);
}
this["radioButton" add clicked].gotoAndStop(2);
selected = clicked;
}
function getSelectedNum(){
return selected;
}
function getSelectedLabel(){
return labels[selected];
}
} [/as]
Let's concentrate on the new parts of the script. We start off by defining the default selected option, in this case radio button #2. Moving down a bit, we make a call to the select function in order to select this default option.
What this function does, as you can see, is that it first loops through all of the radio buttons and unselects them one by one by sending them to their first frame. Next, it simply selects the appropriate radio button by moving it to its second frame, and makes sure to remember which radio button is selected by placing its number in the selected variable.
Our reportClick() function also uses the select() function. It simply checks if the radio button that called it was already clicked, and it not, it asks the select() function to select it.
Finally, we added two extra functions, getSelectedNum() and getSelectedLabel(), in order to retrieve information from our radio button group, that is, the number of the selected radio button and its label.
In the sample movie at the top, I named my group of radio buttons "groupOfRB", and simply made a call to groupOfRB.getSelectedNum() and groupOfRB.getSelectedLabel() in order to know what option you had selected. Knowing this, I produced appropriate feedback for the selected options.
As you can see, creating radio buttons in Flash is not quite as easy as in HTML. The great thing, however, about decision elements in Flash is that you can have instant or almost instant feedback.
Consider the same a|b|c|d type questionnaire in Flash and in HTML, where you only see one question per page. In HTML, you would have to load a new page every time a new question is asked; in Flash, however, you would have only one download. You could produce instant gratification to the user without worries of incompatibilities with different browsers and operating systems. You could even create an animated bar chart of the results! Just imagine the possibilities.
Well, I hope you've enjoyed this tutorial. Next time, we'll learn how to create a time machine and go back in time to prevent Netscape 4 from being released. No, seriously, I'm still looking for suggestions for new tutorials. Please send them to [email:patrickmineault@sympatico.ca], as well as any questions or problems you might have.
As always, if you want to be reminded of upcoming tutorials, please send a blank e-mail to [email:as_for_flash5_dummies-subscribe@yahoogroups.com] with "subscribe" in the subject line.
Until next time, happy scripting!