how-to #7: create 'rollup' boxes

If you log on to the Microsoft web site, you will probably have noticed the boxes to the right of the main panel. These boxes do some interesting things: a border appears when you move the mouse over the title, and if you click the little box to the right of the title, the box (except the title bar) disappears, and the box(es) below it move up. The impression is that each box somehow ‘rolls up’ when clicked and ‘rolls down’ if clicked again.

Have you ever wondered how this works? If so, this page will show you how to implement the technique. Before you start though, be warned that this implementation works best in Internet Explorer 4 or later, or Netscape 6.1. Navigator 4.7 and Opera work okay except that they don’t display the box borders when the mouse moves over the title bar. Also, the tutorial below uses Dreamweaver and an extension by Project VII. You could make it work manually with other editors, but I won’t be explaining how the scripts work, just what they do.

Okay. You’ll need to get the MultiMove Layer extension from either the Macromedia Dreamweaver Exchange or direct from Project VII (it’s free! These chaps are some of the best extension writers in the business. If you haven’t visited their web site, do so now). Once you have installed this, the following steps show you what to do.

steps to take

1. images required

You need the following artwork, which is just the title bar for each box plus the up and down arrows required. If you want to produce your own, the title bar image is 185 x 15 pixels in size, and the two arrow boxes are 15 x 15 pixels. You can use the images below by right-clicking each one and selecting Save picture as… from the popup menu:

      

2. new window

In Dreamweaver, open a new window with a white background and insert a table with 1 column and 1 row. The width should be 300 pixels. Type some placeholder text into the column – doesn’t matter what it is.

3. insert four layers.

We need to insert the DIVs which form the boxes. Two DIVs per box are needed, so if we insert four layers we’ll have two boxes. Insert the first layer (Insert menu -> Layer) and rename it ‘head1’. Give it the following dimensions:

left: 320px
top: 20px
width: 200px
height: 15px

Repeat with three other layers, with the following properties:

Name Left Top Width Height
body1 320px 35px 200px 120px
head2 320px 175px 200px 15px
body2 320px 190px 200px 120px

You have probably realised that the ‘head’ layers take the title bar and arrow images, while the ‘body’ layers hold the box content.

4. add some layer content.

Type some text into the ‘body’ layers – whatever you like, but make sure you don’t add too much for the layer’s size (you can adjust sizes later if you need to).

Then insert the title bar image into both ‘head’ layers. Finally, insert the image ‘uparrow’ into the ‘head’ layers so that it is to the right of the title bar image. You must also give this image a name: call it ‘arrow1’ for the top box and ‘arrow2’ for the lower box.

Your Dreamweaver window should now look something like this:

Screen shot

5. add a new style

Create a new style for the boxes, either in an external style sheet or embedded in the page. The only style you need you should name ‘box1’ and it has the following settings:

top border: 0 pixels
left, right, bottom borders: 1 pixel
border colour (all except top): white (#FFFFFF)
border style: solid

Set the <DIV> elements ‘body1’ and ‘body2’ to have this new style, ‘box1’. Since the borders are the same colour as the background you won’t see a border if you preview the page.

6. scripts

Now we can start adding some scripts. What actions do we actually need? Well, both boxes do the following things:

For the upper box only, the following is also needed:

First, we need to preload the arrow images, so make sure that the <BODY> element is selected, then in the Behaviors panel click the plus sign and select ‘Preload Images’ from the menu. When the dialog box appears, select the two arrow images, ‘uparrow.gif’ and ‘dnarrow.gif’. This avoids any delay when the user first clicks the arrow. Make sure that the event is ‘onLoad’ and that it is attached to the <BODY> element.

7. box borders

The box borders are easy to deal with, so we’ll do those first. Click the title bar image in layer head1. Make sure you select the image, not the <DIV> element it is in. From the Behaviors panel, click the plus sign and choose ‘Change Property’ from the menu. (Note: to choose the right behaviors, you must select ‘Show Events For IE 4.0’ from the Behaviors menu.)

When the dialog box appears, set 'Type of Object' to be the DIV element from the topmost dropdown list. The second list will show ‘div “head1”’ as the selected layer; change this to ‘div “body1”’ from the list. Make sure that the Select radio button is selected, and choose ‘style.borderColor’ from the dropdown. Finally, enter the value #0099FF in the text field at the bottom. This is a light blue which matches the title bar image.

All this behavior does is change the border colour to blue to match the title bar. Click OK. By default, the behavior is probably attached to the onClick event. We want this to be the (onMouseOver) event, so click the little arrow next to the onClick event in the Behaviors panel and choose (onMouseOver) from the list. Note that you may see two ‘onMouseOver’ events, one in parentheses and one not. Choose the one in parentheses - this is important for the boxes to work in Navigator 4.x.

Now repeat the whole sequence exactly, with the following two differences: the property value should be #FFFFFF, and the event must be (onMouseOut). This makes the borders disappear again when the mouse is no longer over the title bar. If (onMouseOut) isn’t available from the list of events, you need to choose ‘Show Events For IE 4.0’ from the Behaviors menu.

You now have to repeat the above sequence for the arrow image in the upper box and for the title bar and arrow image in the lower box.

If you preview the page you should now see the borders appearing and disappearing as the mouse moves in and out of the title bar (IE 4 or greater and Netscape 6 only). If it doesn’t work either you selected the wrong element to apply the property change to, or you chose the wrong event somewhere.

8. change the arrow image

Now we’ll add the behavior to change the arrow image when it is clicked. The problem here is that we need to keep track of which state the box is in – either rolled up or rolled down, and we need to do that for both boxes.

If you switch to code view in Dreamweaver, you should have a script section in the <HEAD> element. At the top of this section, outside any functions, add the following lines:

var b1down = true;
var b2down = true;

These variables will hold either true or false; if true, the box is down (i.e. visible and showing an up arrow) or false (box is invisible and the down arrow shows). We start off with both boxes visible.

Now add a function below these variables which looks like this:

function MB_swapBox(arrow) {

}

This will handle the box disappearing, image switching, and lower box moving up or down. We can add the following code to this function:

function SwapBox(arrow) {
if (arrow == 'arrow1') {
if (b1down == true) {
b1down = false;
} else {
b1down = true;
}
}
else if (arrow == 'arrow2') {
if (b2down == true) {
b2down = false;
} else {
b2down = true;
}
}
}

This skeleton function simply checks which arrow has been clicked using a parameter we will pass to it, then changes the flag to show if the box is currently rolled up or down.

All that’s left is to add an event handler to the image so that something happens when the arrow is clicked. Select the arrow1 image and from the Behaviors menu choose Swap Image. When the dialog box appears, make sure that ‘image “arrow1” in layer “head1”’ is selected. You need to choose which image to swap to when the event occurs, so click Browse… and navigate to the dnarrow.gif image.

Important: make sure that ‘Preload images’ and ‘Restore Images onMouseOut’ are not selected!

Click OK. Now make sure that the (onClick) event is attached to this behavior (by default it’s probably onMouseOver).

If you examine the code, you will see that Dreamweaver has added an event handler like this to the <HREF> element preceding the image:

onClick="MM_swapImage('arrow1','','images/dnarrow.gif',0)"

The path to the image on your machine may of course be different. We need to change that handler. Cut to the clipboard (don't just delete) the call to MM_swapImage so that you are left with:

onClick=""

In the handler, insert a call to MB_swapBox:

onClick="MB_swapBox('arrow1')"

This calls our custom function when the image is clicked. Finally, paste the call to MM_swapImage you cut to the clipboard into the MB_swapBox function twice so that you get this:

function MB_swapBox(arrow) {
if (arrow == 'arrow1') {
if (b1down == true) {
// paste here
MM_swapImage('arrow1','','images/dnarrow.gif',0);
b1down = false;
} else {
// and paste here
MM_swapImage('arrow1','','images/dnarrow.gif',0);
b1down = true;
}
}
… rest of function …

To complete this section, in the second call to MM_swapImage change “images/dnarrow.gif” to “images/uparrow.gif” (or whatever the path is on your machine). This ensures that each time you click the image, it is toggled between the up and down arrows.

Repeat exactly for the second box. The only things you have to change are:

Test this out and make sure it works. If it doesn’t, the most likely cause is that the call to MB_swapBox or MM_swapImage have the wrong arrow image as a parameter.

9. hide the boxes

So far, so easy. Now let’s handle hiding and showing the box. Select the arrow image in the top box again, and from the Behaviors panel menu choose Show-Hide Layers. When the dialog box appears, click ‘layer “body1”’ and then click the ‘Hide’ button. Click OK. Make sure that the (onClick) event is selected for this behavior, so that the image has two onClick event handler functions.

If you switch to code view, you will see that the image has an onClick event handler which now calls our MB_swapBox function plus the Macromedia-supplied function MM_showHideLayers. We need to cut this second event handler and paste it into our MB_swapBox function. The relevant part of the function will then look like this:


if (b1down == true) {
MM_swapImage('arrow1','','images/dnarrow.gif',0)
MM_showHideLayers('body1','','hide')"
b1down = false;
} else {

Copy the line which calls ShowHideLayers and paste it into the function below each call to MM_swapImage (i.e. paste it three more times). We also need to:

The whole function now looks like this:

function MB_swapBox(arrow) {
if (arrow == 'arrow1') {
if (b1down == true) {
MM_swapImage('arrow1','','images/dnarrow.gif',0);
MM_showHideLayers('body1','','hide');
b1down = false;
} else {
MM_swapImage('arrow1','','images/uparrow.gif',0);
MM_showHideLayers('body1','','show');
b1down = true;
}
}
else if (arrow == 'arrow2') {
if (b2down == true) {
MM_swapImage('arrow2','','images/dnarrow.gif',0);
MM_showHideLayers('body2','','hide');
b2down = false;
} else {
MM_swapImage('arrow2','','images/uparrow.gif',0);
MM_showHideLayers('body2','','show');
b2down = true;
}
}
}

Try it out and you’ll see that the boxes appear and disappear with each click, plus the arrow image changes.

10. move the box

The only thing left to do is to handle the movement of the lower box. This is why we need the Project VII extension MultiMove Layers.

Select the arrow image in the top box again, and from the Behaviors popup menu choose the Studio VII sub-menu and the behavior MultiMove Layers By PVII. When the dialog box appears, ensure that the layer head2 is selected in the list of layers to move. Then from the Preset menu choose ‘Up 100 px’ (note that the method turns to ‘Relative’). Add layer body2 to the list and repeat the preset movement. Click OK and make sure that the event is (onClick) – i.e. with parentheses. It might be set to onClick without parentheses – change this if so.

This behavior once again appears as an onClick event handler for the image and it looks like this:

P7_MultiMove('head2',0,-100,1,'body2',0,-100,1)

It is very important that both layers move up 100 pixels; it’s easy to change only one layer so that things don’t work as expected. Check that your function call looks exactly like the above.

Now cut it out from the onClick handler and paste it twice into the SwapBox function below the call to MM_showHideLayers for arrow1. (You don’t need to do this for the lower box (arrow2) as we aren’t going to move the upper box if the lower one is rolled up.) Finally, in the second call to MultiMoveLayers, change the parameter –100 to 100 (i.e. remove the minus sign). Make sure you do this for head2 and body2. This moves the layers back down again when the down arrow is clicked.

When you are finished, you should have a single onClick event handler for each arrow image which simply calls MB_swapBox. This does the rest by calling the various other functions with the correct parameters.

As a final refinement you could use another couple of Project VII extensions. The IE Link Scrubber removes the nasty dotted lines around the arrow images when they are clicked. The N4 Return False Fix stops Navigator 4.x displaying the hourglass cursor when a null link is clicked. Get these extensions from the same place as MultiMove Layers.

And that’s it! Try it out and it should all work as expected. If you have problems in Navigator 4.7, check that the layers are not contained within the table you inserted – you’ll have to inspect the code for this. Also, check that the JavaScript is perfect with all terminating semi-colons. Finally, if you set any padding in the style for the box, Netscape 6 won’t like it and will draw the box too big so that the title bar and body are misaligned.

To see a test of the finished result, follow this link.