For more about CSS and Layers, see Chapter 14, "Using Layers for Page Layout."
enables you to climb up the document "tree" to talk to a text field inside a form, inside the document that is currently inside the browser window, and finally to change that text field's value. By accessing that value, you have just navigated the DOM.
Like everything else about computers, the DOM develops and has versions. Basic form access, like that shown here, is part of the Level 0 DOM. The more total page access used for Dynamic HTML requires the more developed Level 1 DOM. Only browsers 4.0 and above can understand the Level 1 DOM; therefore, only those browsers can handle DHTML.
The DOM is important to you because all DOMs are not the same. The single biggest problem facing most DHTML developers is that the Netscape DOM the hierarchy you must use to access page elements in that browser is very different from the Internet Explorer DOM. The IE DOM is more sophisticated and more in line with the official Level 1 DOM standards set by the W3C. Though the Netscape 6 DOM is closer to the standard than the Netscape 4 DOM, it's still not the same as the IE DOM. This means that, even if you consider only these two major browsers, you have three different DOMs to deal with.
In general, DHTML authors have a choice of the following:
Pick one browser to design for, and ignore the rest.
Try to be as inclusive as possible by using only features that work everywhere.
Try to be reasonably inclusive but also use new features, by putting two or more sets of code in each page, each directed at a different browser.
You can never be completely shielded, however. Certain items will display differently across browsers and across platforms in different browsers. Certain behaviors will behave differently in different browsers or they won't behave at all, despite Dreamweaver's robust coding. This chapter focuses on how to use Dreamweaver tools for dynamically controlling layers. Be aware, as you go through it, that not everything you do will work equally well in all browser/platform situations.
One of the simplest, and most reliable, layer properties you can control with scripting is visibility. By dynamically hiding and showing layers, you can create pages that store much more information than is visible at any given time. The designer's buzzword for this is nested content. Nested content can include contextual information popping up where needed, drop-down navigation menus, and different sets of body content that display as users click navigation controls. The possibilities are limited only by the designer's imagination and ingenuity.
You control layer visibility in Dreamweaver with the Show-Hide Layers behavior. As Figure 17.1 shows, it's simple and straightforward to use.
Visibility control as scripted by Dreamweaver is supported by Netscape Navigator 4 and 6, IE 4-6, and Opera 5 6 across platforms.
As with any behavior, start by creating the layer to show or hide, and selecting the object that will trigger the visibility change. Showing and hiding can be triggered by rollovers, mouse clicks, form data changes, or even pages loading. Then follow these steps:
In the Behaviors panel, choose the Show-Hide Layers behavior.
In the dialog box that appears, select a layer from the list.
Choose the visibility state you want it to have.
Repeat steps 2 and 3 for any other layers you want to change with this instance of the behavior.
Note that you can change the visibility of as many layers as you like, in this one dialog box, with just one instance of the Show-Hide behavior. If you have three alternate content layers, for instance, one instance of Show-Hide will show one content layer and hide the other two. (That's the scenario being illustrated in Figure 17.1.) Here are a few other tips.
What's the difference between setting the property initially and using the behavior to set it onLoad? Behaviors that execute onLoad will execute only after the page has finished loading. You can, for instance, create a loading screen by making a layer containing the word Loading, and setting it to start out visible, but become hidden onLoad.
When you choose the Show-Hide behavior, you have three visibility choices. Show and Hide are self-explanatory. Default sets the visibility state to inherit. (See Chapter 14 for a full discussion of inherited visibility.)
What if you're in the Show-Hide dialog box, and you've selected a particular layer and set it to show or hide, and then you realize you had the wrong layer chosen? You don't have to cancel the whole operation. Just choose the same option for the same layer again to toggle it off. If you've set the layer "Fred" to "show" by mistake, for instance, just leave Fred selected and click the Show button again.
After you start working with this behavior, you are likely to run into the following situation. You've created a layer that will start out invisible, until the user clicks a button or mouses over something that makes it show. How do you continue working with the layer in Design view, now that it's invisible? One solution is to leave it visible until you've finished editing the page. The very last thing you'll do before saving, closing, and uploading the file is use the Property Inspector or Layers panel to set the layer's visibility to Hidden.
For any of you who have less-than-perfect memories, however, this is a dangerous idea, because it's easy to forget that last step when you're facing down a deadline and have a million things to do. Instead, use the Layers panel to select your hidden layer. Clicking a layer's name in the panel will select it, and as soon as it's selected, it will become visible and will stay visible as long as you're editing its contents. As soon as you deselect it, however, it will disappear again. Making the layer temporarily visible in this way doesn't change the HTML code at all (that is, the code still defines the layer as being invisible), so there's no danger of it getting uploaded and displayed on the web improperly (see Figure 17.3).
Exercise 17.1 Creating a Drop-Down or Cascading Menu
In this exercise, you'll create one of the most popular hidden-layer effects, a graphic menu bar with menus that appear when the mouse rolls over topics on the menu bar. This sort of menu is called a drop-down menu when the menu bar is placed horizontally across the top of a page (like the menu bars in standard applications), and a cascading menu when the menu bar is vertical and the menus appear to the side. All files for the exercise are located on the CD in the chapter_17/menus folder.
If you haven't done so already, copy the chapter_17 folder to your hard drive and define a site with that folder as the local root folder.
Start by opening dropdown.html and examining its contents and structure. This file contains four layers one for the menu bar and three for the menus that will appear from it. The three menu layers are nested within the main menu bar layer, so the whole menu system can be repositioned by moving only the main layer. Preview the file in a browser and you'll see that the first of the menus already contains rollovers for each entry (see Figure 17.4).
When working in depth with layers, an important habit to get into, is giving them names you'll recognize when you see them in a dialog box or inspector. Before proceeding with the scripting in this exercise, take a moment to rename the layers. Name them "main," "books," "music," and "video."
The three books, music, and video layers should initially be invisible. Using the "eyeball" column in the Layers panel, make the books, music, and video layers invisible by clicking until the closed eye icon shows (see Figure 17.5).
You want each menu to appear when the user mouses over the appropriate title in the menu bar. This means attaching the Show-Hide behavior to the three main graphics in the menu bar. Start with the BOOKS image.
Select the image.
Open the Behaviors panel, and choose Show-Hide Layers from the actions list.
In the dialog box that appears, from the list of layers, find "books" and set it to "show" (see Figure 17.6).
When you're done, click OK to close the dialog box.
After you've applied the behavior, check the Behaviors panel to make sure the (onMouseOver) event trigger is chosen. (Remember to use the event trigger that appears in parentheses, to ensure maximum cross-browser compatibility. For more on this, see Chapter 16, "Getting Interactive with Behaviors.")
Preview in Browser to make sure the behavior is working. Then repeat the above procedure for each of the other two menu topics.
After you've applied all three behaviors, the menus should appear on cue but they never disappear. The mechanics of making that happen aren't difficult it's just a matter of applying another Show-Hide behavior. But what event should trigger the behavior? That's a matter of strategy.
One strategy is to make each menu button (BOOKS, MUSIC, VIDEO) trigger its own menu to show and the other menus to hide. To accomplish that, select one of the menu title graphics BOOKS, for instance and, in the Behaviors panel, double-click its Show-Hide behavior to edit it. For the BOOKS graphic, the books layer should already be set to show. Select the music layer and set it to hide; then set the video layer to hide also. Using this one behavior, you've now created a script that shows one menu and hides the other two (see Figure 17.7).
Repeat this process for each of the three title graphics. Rolling over any menu title should show that title's menu and hide the other two menus.
When you're finished, check out the result in the browser. Assuming that your users will check out each of your menus and then choose a destination from one of them, your menu system should work perfectly. There's one niggling interface flaw remaining, however. What if your visitors check out all the different menus, and then decide not to choose a destination from any one of them? After the menus have started showing, there's no way to get all three of them to hide. Again, this is a matter of strategy. What event can be used to trigger all menus hiding?
A sneaky solution is to put another layer behind all of the menu layers, fill that layer with an invisible image, and set that image to trigger all menus hiding when it is rolled over. Figure 17.8 shows this happening.
Start by drawing a new layer. Make it large enough to cover the entire area of your menu bar and menus. While you're at it, jot down its width and height from the Property Inspector. (Don't nest the background layer in with the main layer, or the effect won't work.) Because it will sit behind the other layers, as a kind of invisible background for them, name it menubg.
Arrange the new menubg layer behind all the other layers by going to the Layers panel and dragging it to the bottom of the list of layers.
With the cursor inside this new layer, use the Image object from the Insert bar to insert trpix.gif. This transparent, single-pixel GIF image is located in the chapter_17/menus/images folder with the rest of the image files for this exercise. Set the width and height of the image to match the dimensions of your layer.
With this large transparent image selected, go to the Behaviors panel and add another Show-Hide Layers behavior. Set this behavior to hide all three menu layers. Set the triggering event to onMouseOver or (onMouseOver).
When you're finished, preview the page in a browser. When a menu is showing, moving the mouse away from the menu should hide all menus.
What's happening here? When the mouse rolls over the transparent image, all menus will hide. But when the mouse is over another image, in another layer, which is in front of the transparent image, its event handler is disabled. So, effectively, you've created a trigger that will hide all menus only when the mouse is in the vicinity of the menu system but not actually over any menus or the menu bar.
Should you use onMouseOver or (onMouseOver) as the trigger for the transparent image? As was discussed in Chapter 16, any time an <img> tag is selected, you have a choice of event triggers with or without parentheses. Choosing a trigger with parentheses will add the behavior's function call to an <a> tag surrounding the image (and will even create the <a> tag, if necessary). Choosing a trigger with no parentheses will add the function to the <img> tag itself. Since Netscape 4.x does not support event handlers for <img> tags, it's safer to use the triggers in parentheses. But adding an <a> tag also causes the cursor to change to a pointing finger. This is the user's cue that a link is present. In the case of your menu system, users are going to be confused if, any time the mouse gets anywhere near the hidden menus, the cursor changes to indicate a link. That's bad interface design.
For this exercise, try the menu system out both ways with onMouseOver and (onMouseOver). See what the difference means to you. Figure 17.9 shows what the user will see if you choose the safer (onMouseOver) event handler.
To access the nonparenthetical onMouseOver trigger, set the event handlers pop-up menu to show events for IE 4.0.
Optional challenge: Can you see how the menu system you've just created could function as a vertical menu bar with cascading menus, without any change in scripting? The only changes required are layout changes altering the table structure of the main layer, the relative positions of the various menu layers, and the dimensions of the invisible image and layer in the background. See if you can create a sideways cascading menu from this file. If you get stuck, check out cascading_finished.html, in the chapter_17/menus folder for a completed example. Figure 17.10 shows a cascading menu system in action.
The actual mechanics of applying this behavior are not complicated. However, working with invisible page elements brings up a host of questions that you'll undoubtedly stumble across when you least expect them. Here are a few points to consider.
Any content within an invisible layer is still considered part of your page. It will download when the page downloads. This has all sorts of ramifications. If your page contains many layers that are initially invisible, and if those layers have substantial content in them, your page will take a while to download even though it looks like a simple, fairly empty page. If a user clicks a button that makes a layer visible, and that layer's contents haven't finished downloading yet, he'll experience a delay. After the page has finished downloading, however, layers that become visible will display immediately. In essence, you've preloaded the contents of those layers.
Because layers can contain just about anything, your layers might include buttons or text links that have their own behaviors attached to them. Be aware that triggers won't work if a layer is invisible. If you have a rollover set to open a new window when the mouse moves over it, and that rollover is hidden in an invisible layer, no visitor is going to accidentally trigger the new window opening by moving his mouse over that hidden item.
Embedded video, audio, Flash movies, and other media objects can be placed in layers (see Chapter 19, "Plugins, ActiveX, and Java," for more on this); but this limits the functionality of the layers. Depending on the browser, the platform, and the media plugin involved, the layer might not become properly invisible, or it might not be possible to change layer visibility with scripting. If you want to use media objects in conjunction with DHTML effects like this, test your pages carefully in all target browsers.
An alternative approach to putting nested content on pages is to change the contents of a single layer, instead of hiding and showing multiple layers. In Dreamweaver, you do this with the Set Text of Layer behavior.
As coded by Dreamweaver, the Set Text of Layer behavior works in IE 4+, Netscape 4.x, and Netscape 6.x. It will not work in Opera 5-6.
The Set Layer Text behavior is tucked away in the Set Text submenu of the Behaviors panel's Actions pop-up menu. Choosing it brings up a dialog box in which you can choose any of your document's layers and enter any text you want to appear in that layer (see Figure 17.11). Whatever you enter here will replace the existing layer contents regardless of the contents. You can even change the contents of the layer containing the object the behavior is attached to. If you leave the dialog box's input area empty, the contents of the specified layer will be deleted.
What can you do to really take advantage of this behavior?
Despite its name, Set Text of Layer is not limited to text effects. You can use it to put almost any content into a layer, by entering HTML code rather than straight text into the input field of the dialog box. Code such as
<h1>Welcome!</h1> <p>Are you ready for the <b>big</b> moment?</p>
will display a formatted text message in the specified layer. Tables and images, links, and forms can all be written into layers using this behavior. A more accurate description for the behavior might be "Set HTML Content of Layer."
Here are a few tips to consider when using Set Text of Layer.
Whatever text or HTML you enter in the dialog box will be inserted into the behavior's function call, like this:
If you have set your Code Rewriting Preferences to URL-encode special characters and attribute values, any HTML source code you enter will be inserted into your page code looking like this:
onClick="MM_setTextOfLayer('help','','%3Cimg src=%22duck.gif%22 width=%2250%22 height=%2250%22%3E')"
While this code will work perfectly fine in a browser, it isn't too readable if you later want to hand-edit your HTML. You can avoid this mess by going to Edit > Preferences > Code Rewriting (Mac OS X: Dreamweaver > Preferences > Code Rewriting) and disabling both Special Characters options the Encode Special Characters in URLs and Encode <, >, &, and " in Attribute Values Using & options. With these options deselected, Dreamweaver will escape all quotes with \ and leave all other characters alone. If you do this, however, you must only include single quotes in your HTML code. This code, for instance, will break the behavior:
<img src="duck.gif" width="50" height="50">
But this code will work fine:
<img src='/books/1/75/1/html/2/duck.gif' width='50' height='50'>
It will be inserted into your page code as the following function call:
onClick="MM_setTextOfLayer('violin','','<img src=\'duck.gif\' width=\'50\' height=\'50\'>')"
For a full discussion of functions and function calls in Dreamweaver behaviors, see Chapter 16. For more on the Code Rewriting preferences, see Chapter 33, "Writing Code in Dreamweaver."
If you want to insert HTML formatting using Set Text of Layer, but don't want to type all that code yourself, work smart with Dreamweaver. Create the desired display in Design view, either in the same file you're working on or in a temporary file; then go to Code view and copy the code from there. Open the Set Text of Layer dialog box, click in the input area, and paste. Remember, though, that Dreamweaver always encloses tag attributes in double quotes. So if you have disabled the Special Characters options as described earlier, you'll have to replace all double quotes with single quotes, either by hand or using the Find & Replace command, before the behavior will work.
Browsers won't display embedded media properly when the <embed> code appears as part of this command. Media objects and layers often don't mix well.
Exercise 17.2 Setting Layer Text to Display Context-Sensitive Information
This exercise builds an interactive illustration that puts different data in an information layer depending on what part of the illustration the mouse rolls over. All the files for the exercise can be found in the chapter_17/violin folder on the CD.
Open and examine violin_write.html. This file, pictured in Figure 17.12, presents the user with a picture of a violin. Image map hotspots will be used to trigger a behavior that puts different information in the help layer as the user's mouse rolls over those parts of the illustration. If you browse this file, you'll see that some of the hotspots already trigger basic text-only information to appear. You'll be adding the same behavior to the remaining hotspots and then dressing up the way the contextual information displays. (To see the final presentation in action, browse violin_write_finished.html.)
Select the hotspot at the top of the violin picture. Open the Behaviors panel and choose Set Text of Layer from the Actions list. In the dialog box, choose the help layer from the pop-up menu, and type the word Scroll in the input field. After you have finished, make sure the event triggering the action is onMouseOver. Figure 17.13 shows the dialog box with information entered.
You also need to blank out the help layer when the mouse rolls off of the violin scroll. With the same hotspot selected, add another instance of the Set Text of Layer behavior. Choose the help layer from the pop-up menu again, but this time leave the input field blank (enter no text). When you're done, change the trigger event to onMouseOut.
Repeat the procedure for the hotspot directly below this one, configuring it to show the word Neck onMouseOver. Make sure you preview in the browser, to make sure you've coded the effect properly, before proceeding to the next step.
Now make the Scroll and Neck messages a bit fancier. Select the top hotspot, and double-click its onMouseOver behavior to edit the text that will appear. Replace the original message with this code:
<h1>Scroll</h1> <p>Scrolls are curly and brown, and have wooden pegs sticking out of both sides.</p>
Close the dialog box and Preview in Browser. Rolling over the violin scroll should now display information like that shown in Figure 17.14.
After you've verified that your behavior is working, check your code to see how the HTML was inserted into the function call. (You can do this quickly by going to Code and Design view and selecting the hotspot in the Design View portion of the Document window.) Depending on how your URL encoding preferences are set, you might see a mess like this:
<area onMouseOver="MM_setTextOfLayer('violin','','%3Ch1%3EScroll%3C/h1%3E%0D% 3Cp%3E Scrolls are curly and brown, and have wooden pegs sticking out of both sides.%3C/p%3E')" shape="rect" coords="65,3,145,89" href="#">
To clean up this code, go to Edit > Preferences (Mac OS X: Dreamweaver > Preferences), and choose the Code Rewriting category. Deselect both Special Characters options. After this is done, return to the Behaviors Panel and double-click the scroll hotspot's Set Text of Layer behavior to open its dialog box. You don't need to change anything in the dialog box; just click OK. Check your code again, and you should see a more readable function call than before:
<area onMouseOver="MM_setTextOfLayer('violin','','<h1>Scroll</h1><p> Scrolls are curly and brown, and have wooden pegs sticking out of both sides.</p>')" shape="rect" coords="65,3,145,89" href="#">
For the Neck hotspot, use Dreamweaver to help write the formatted code. Create a new Dreamweaver file, and save it in the chapter_17/violin folder as temp.html.
In temp.html, type the following text:
Neck Violin necks are long and skinny, and since they're made of wood they're not much good for swallowing.
Now use the Property Inspector to format the first line as <h1> and the rest as <p>. Go to Code view, select all the HTML code for the formatted text, and copy it. (If you copy directly from Design view, you'll get only the text, not the formatting code.)
Back in violin_write.html, select the Neck hotspot and open its Set Text of Layer behavior for editing. Delete the contents of the input field and paste in the HTML code from the temporary file. Preview in Browser again; rolling over the Scroll and Neck hotspots should display similarly formatted text in the help layer. If you changed your Code Rewriting preferences in the previous step, your page's source code should contain a nice, readable (non-encoded) chunk of HTML in the Neck hotspot's function call.
To make things even fancier, replace the <h1> title with a GIF image, again using the temp.html file as a handy code-creating workshop.
Open temp.html (or bring it to the front) and go to Code and Design view. In the Design portion of the Document window, delete the heading, and in its place insert the image scroll.gif. Figure 17.15 shows how the revised scroll message should appear in the temp file.
If you have disabled URL encoding in your preferences, you'll need to replace all double quotes with single quotes. To do this, go to Edit > Find and Replace. Set your search parameters to Current Document and Source Code. Search for double quotes (") and replace with single quotes ('). Since this is only a temp file, go ahead and click the Replace All button to perform the search quickly.
When this is complete, activate the Code view portion of the Document window, and select and copy all the code for the image and text. Then go back to violin_write.html, open the Scroll hotspot's behavior for editing, and replace its contents with the new code.
Preview your violin page in the browser. If you entered your code correctly, you should see a result like that shown in Figure 17.12. If your browser preview doesn't work properly, double-check the code for your page. The scroll hotspot's event handler should contain escaped single quotes.
Let Dreamweaver's color coding work for you. If your pasted code contains incorrect quote marks, the improperly terminated string literals will turn blue. If the quote marks are correct, the entire function call (everything after onMouseOver=) will be pink.
If you want to complete the violin-browsing experience and get some practice with this behavior, repeat the previous steps to dress up the rest of the violin hotspots. All the required GIF images are in the chapter_17/violin folder.
A lovely, efficient way to put nicely formatted text into a layer without having to enter and reenter the HTML formatting for each new set of text is to assign a custom CSS class to the layer itself. It works this way (see Figure 17.16):
Create the layer you're going to be targeting with the behavior.
Using the CSS Styles panel, create a new custom class. Include any text formatting, positioning, or layer formatting you like in this style.
In Design view, select the layer and apply the style to it.
After this is done, whenever you Set Text of Layer, you need to enter only the text itself. All formatting will be supplied.
Repeatedly setting the text of a single layer can create a similar effect to starting with a stack of hidden layers and showing them one at a time. Why choose one method over another?
Loading and preloading. If all of the document's content is present when the page initially loads (as it is when using Show-Hide Layers), it will all display immediately when called on. Depending on your project, you might decide that this is a good thing, or not. If you know ahead of time that users are probably going to access all the content, you'll want to download it as soon as possible so use Show-Hide Layers. If you think users will probably want to access only one or two layers' worth of contents, you might not want to make them wait for the other layers' content to download so use Set Text of Layer.
Simple text changes. If your content all consists of similarly formatted text, it will probably be more efficient to create and edit content using Set Text of Layer. You can use a CSS style applied to the layer to control formatting, and need only enter unformatted text in the behavior's dialog box.
Different content, identical layers. If your content will all appear in the same position on the page, it's easier to format, resize, and position one layer than several. Use Set Text of Layer.
Browser compatibility. Setting layer text as it is scripted in the Dreamweaver behavior is supported by all current versions of Netscape and IE, but not by Opera. If this extra browser support is important to you, stick with Show-Hide Layers.
It's easy in Dreamweaver's Design view to move layers around on the page, but after the page is created and published on the web, everything is cemented in place. Or is it? With the Drag Layer behavior, you tell layers to track the coordinates of the user's mouse. You can use this scripting to create repositionable navigation menus and pop-up windows, drag-and-drop games, shopping carts, and even slider controls.
Note that the Drag Layer behavior as implemented in Dreamweaver will not work in Netscape 6 or in Opera.
Applying the Drag Layer behavior is not as straightforward as applying the other layer behaviors, because it must be triggered when the page loads, not when the user presses the mouse down on a layer. What you're doing is declaring a given layer to be "draggable" after that, it's up to the user to drag it around or not. To set up a draggable layer, follow these steps:
Open or create a document that has at least one layer in it.
Deselect all page content, or use the tag selector to select the <body> tag.
Open the Behaviors panel and choose the Drag Layer behavior from the Actions list. In the dialog box that appears, use the pop-up menu to select the layer that you want to be draggable. Configure any other settings as desired, or leave the default settings in place.
Make sure the event triggering the action is onLoad.
That's it! For the life of this document, the layer is draggable. Figure 17.17 shows the Drag Layer behavior dialog box, with its various options diagrammed.
You can customize a layer's draggability in various ways. You can control which portion of it is draggable, where and how far it can be dragged, what happens to its z-index (position in the stacking order) as it is dragging, and what should happen when the user drops it. Some of these options can be tricky to use, but they are responsible for the power of the behavior.
If you apply no constraints, the user is free to drag the layer anywhere within the browser window. Depending on why you've made the layer draggable in the first place, you might want to limit users to dragging only within a certain area. If you're creating a game, for instance, you might want the draggable game pieces to stay within the defined game boundaries.
Assigning a constraint area is easy: Just select the Constraint option from the Movement menu in the Basic tab of the Drag Layer dialog box.
The tricky part is determining what constraint values to specify in the four text fields. These fields all ask the same question: Starting from its current position, how many pixels up/down/left/right should the layer be allowed to move? Depending on what kind of constraint you're trying to create, figuring these values out can be simple or it can require some tinkering and thought.
If you love solving engineering problems and are good at diagramming and math, you probably don't need any help with this. For everybody else, here's a simple strategy:
Grab a pencil and paper, and in Dreamweaver open the History panel.
Select the layer you want to constraint, and write down its starting L (left) and T (top) position.
Drag the layer to the topmost, leftmost position you want it to go. Note the new T (top) position, and subtract it from the starting T value. That's your "up" value. Note the new L (left) position, and subtract it from the starting L value. That's you're "left" value.
Drag the layer to the bottommost, rightmost position you want it to go. Note the new T position, and subtract the original T value from it. That's your "down" value. Note the new L position, and subtract the original L value. That's your "right" value.
If you're not sure which value to subtract from which, just remember that all constraint numbers must be positive integers, or 0. (A value of 0 means the layer isn't allowed to move in that direction.) Subtract the smaller from the larger. Figure 17.18 shows a form you might find handy for your note taking.
A drop target is the location where you want the user to drop the layer. If you're creating a game, such as a matching game, this would be the location of the correct answer. If you're creating a shopping cart interface, this would be the cart graphic that tells you the user wants to buy an item. This option is specified in the Basic tab of the Drag Layer dialog box.
You specify the drop target as Left and Top coordinates, which represent where the upper-left corner of the layer should be when it's dropped. Because it's almost impossible for a user to drop a layer on exactly those coordinates (not one pixel right or left, up or down), you enable snapping and assign a "snap-to" distance, also measured in pixels. If the user drops the layer within that many pixels of the target, the layer snaps into place and is officially on target.
How do you figure out what values to use for the drop target? The dialog box gives you a helpful Get Current Position button click the button and the current coordinates of the draggable layer will be entered. This is useful, however, only if the layer is currently sitting at its target location. Therefore, one way to approach the problem is to close the dialog box, move the layer to its desired destination, return to the dialog box, and click the button. Then close the dialog box again and move the layer back to its starting position.
Another way to handle this situation is to move the layer to the drop target destination, write down the coordinates, and then choose Edit > Undo or use the History panel to put the layer back where it started. Then go to the dialog box and type in the values you wrote down. (The second method has the advantage of putting your layer back in exactly the same position where it started.)
Do you want the user to be able to click anywhere on the layer to start dragging it, or can he drag only from a particular location (like a handle)? If your layer contains a puzzle piece or shopping item, for instance, you probably want the entire layer to be draggable. If it's an interface item, however, like a mini-window or Popup Message, you'll probably want users to drag it only by its title bar (just like a real computer window).
Choose the Area Within Layer option from the Drag Handle menu in the Advanced tab of the Drag Layer dialog box. Text fields will appear, asking you to specify the drag handle's left edge, top edge, width, and height. The left and top measurements are relative to left and top of the draggable layer. To use a temporary layer to determine the appropriate values for a drag handle, follow these steps (demonstrated in Figure 17.19):
Draw a temporary layer to use as a proxy for the drag handle. Resize and position this layer to where you want the handle to be.
Jot down the new layer's W, H, L, and T values from the Property inspector.
Select the draggable layer, and jot down its L and T values. The temporary layer's W and H values will become the drag handle's W and H.
Subtract the draggable layer's L and T values from the temporary layer's L and T values, to get the drag handle's L and T values.
When you're done, delete the temporary layer.
If you repeatedly find yourself scratching your head over pixel coordinates and measurements, try using an onscreen pixel ruler utility. You can find plenty of them available at shareware sites such as www.download.com.
The z-index determines which layers are on top of which other layers. While a layer is being dragged, it should probably be on top dragging a layer that goes behind other layers is a weird experience. When the layer is dropped, you might want it to stay on top, or you might want it to return to its normal position in the stacking order. Use the Advanced tab of the dialog box to specify how the z-index is treated.
Exercise 17.3 Creating a Draggable Shopping Cart Interface
In this exercise, you use the Drag Layer behavior to create a graphic shopping experience where visitors can drag shopping bags into a cart. All the files for this exercise can be found on the CD in the chapter_17/shoppingcart folder.
Start by opening shopping.html and examining its contents (see Figure 17.20). All the page elements are in place, and the layers have been given descriptive names. None of the scripting has been added.
You want all three shopping bag layers to be draggable, so you need three instances of the Drag Layer behavior, each triggered when the page loads. Deselect all page content, or use the tag selector to select <body>. Then open the Behaviors panel and create a Drag Layer behavior for each shopping bag. Preview in the browser to make sure the bags are indeed draggable.
For your first refinement, limit the draggable area for the shopping bags. You don't want users dragging and dropping bags on top of the title bar or shopping instructions, so define an official "shopping area" from the bottom of the title bar to the bottom of the shopping cart, and from the left edge of the price fields to the right edge of the shopping cart.
Before plunging back into the dialog boxes, you need to calculate the Up, Down, Left, and Right constraint values for each bag. Using the method outlined earlier (or any other method you like better), determine the values for each bag. Then configure each Drag Layer behavior instance with the correct numbers. Figure 17.21 shows the editing dialog box for the red bag layer, with appropriate values entered.
Now set drop targets for all three bags.
Move all three bags to where you think their final destination should be in the cart (see Figure 17.22). For all three, jot down their L and T values. Then use Edit > Undo or the History panel to put the bags back to their original positions, and enter each bag's values in the appropriate Drag Layer dialog box. For each bag, enter a snap-to distance of 100 pixels.
You want each bag to come to the front as you're dragging it. When the bags are dropped, however, you need to reset the z-index so that they end up sitting inside the cart rather than on top of it. Open up each Drag Layer behavior and bring the Advanced tab to the front. Make sure that Bring to Front is selected and choose Restore z-index from the pop-up menu.
Try it out! In browsers that support the Drag Layer behavior, you should be able to drop items in the shopping cart or leave them lying around the window but not outside your official shopping rectangle.
Being able to drag items around onscreen might be fun, but it can really be useful when you use it to trigger other actions. If the layer is a slider, if it's a game, or if it's a shopping cart, you might need to know three things:
That an object is currently being dragged
That an object has been dropped
That an object has been dropped on target
Another handy one-liner to use with Drag Layer is location='anypage.html', which will cause the browser to go to the specified relative or absolute address as soon as an item is dropped on a target.
Exercise 17.4 Responding to Items Dropped in a Shopping Cart
In this exercise, you'll add more functionality to the draggable shopping cart developed in the preceding exercise. If the user drops a shopping bag in the cart, you'll trigger another script that responds in various ways.
If you completed the preceding exercise and are happy with your results, open the shopping.html page you created. If you would rather start fresh, open shopping_finished.html from the chapter_17/shoppingcart folder on the CD. Whichever file you open, save it as buying.html.
window.alert('You bought me!')
This nice simple statement will make a Popup Message appear. So that the message appears only if the bag is in the cart, select the Only If Snapped option. Try the new improved shopping cart out in your browser. Dragging the bag to the cart should call up a pop-up window like the one shown in Figure 17.25.
Now get your shopping cart to do something fancier, by inserting a function call for a Dreamweaver behavior. You'll make your document's three price layers invisible to start out with and then have each one become visible as its matching bag is dropped in the cart.
To set up the effect, make each of the price layers (redprice, greenprice, blue-price) invisible, by closing its eye in the Layers panel.
Following the steps outlined earlier, you'll start by adding a fake text link. Create a new, small layer somewhere on your page. Type the words buy me!, or some other simple word or phrase, into the layer, and use the Link field in the Property inspector to link the text to "#". Figure 17.26 shows this happening.
With the text link selected, use the Behaviors panel to add a Show-Hide Layers behavior. In the behavior dialog box, configure it to show the redprice layer. Before proceeding, test this behavior in the browser to make sure it's working properly.
Now copy the function call. Select the text link and go to Code view or Code and Design view. The code for the text including its <a> tag, event handler, and function call should be selected and therefore easy to locate. Deselect the code, and select only the function call. Your code and selection should look like this (selected code is shown here in bold):
<div id="Layer1" style="position:absolute; left:263px; top:116px; width:138px; height:61px; z-index:7"><a href="#" onClick="MM_showHideLayers('redprice','','show')">buy me! </a></div>
Copy the selected code and go back to Design view.
Now paste the function call into the Drag Layer behavior. In the Behaviors panel, find the Drag Layer instance that controls the red shopping bag, and open its dialog box. In the Advanced tab, if there's any code written in the When Dropped field, delete it. Then paste the function call into that input field. Your dialog box should now look like the one shown in Figure 17.27.
Try the result in your browser! If it doesn't work, check the pasted function call and make sure you pasted exactly the code shown in Figure 17.29 (that is, everything after the onClick event handler and between the double quotes).
Finally, delete the layer containing the text link, because you don't need it anymore. Select the layer in Design view, and then go to Code view. Make sure you have everything including the <div> tags selected, and delete. Then scroll up to the top of the page to make sure the MM_showHideLayers() function is still present. After you've done this, check the page in a browser again to make sure the behavior still works.
You still need to add the same behavior to the other two shopping bags. Although you could go through the entire process again (yuck) for each bag, with a tiny bit of hand coding you can accomplish your task quickly and easily.
The function call for Show-Hide Layers should still be on the Clipboard from your preceding copy-paste action. In the Behaviors panel, open up another of the Drag Layer instances. In the dialog box, note which shopping bag this instance is controlling (green or blue). Then bring the Advanced tab forward, click in the When Dropped text field, and paste again. Examine the pasted code. Find the reference to redprice, and change the color name to match the color of this bag. Repeat this process for the third Drag Layer behavior instance, and all three of your shopping bags should now be scripted.
Aren't you glad you gave your layers easy-to-remember names like redprice, greenprice, and blueprice? This is a good example of the importance of good naming conventions as you work.
In the Behaviors panel, open one of the Drag Layer instances and bring the Advanced tab forward. In the second input field (the one you just filled in), drag to select the entire function call entry and copy. Paste that code into the first input field. In the first field, find the reference to show and change it to hide. Everything else remains the same. Your first code entry will read as follows:
The second entry will look like this:
Repeat this process for the other two Drag Layer instances and try the finished page in the browser. As soon as you start dragging a shopping bag, the price will disappear; if you drop it in the cart, the price will reappear. (If you get stuck, buying_finished.html contains the completed exercise.)
You've changed visibility, you've changed the contents, and you've dragged layers around. However, those are only a few of the layer properties you can control. Depending on which browser(s) you're scripting for, you can change background color, position, width and height, style, and clipping you name it. The Dreamweaver general, all-purpose behavior for controlling everything not covered by other behaviors is Change Property.
This behavior isn't just for changing layer properties. It's more of a catch-all behavior for changing any property of any scriptable page element. Depending on the browser you're targeting, and the DOM it supports (see the discussion on DOMs at the beginning of this chapter), you can change properties for form elements, various kinds of layers, and even images. Figure 17.28 shows the Change Property dialog box with its various parts identified.(See Chapter 11, "Working with Forms," for a discussion of using this behavior with form elements.)
To use Change Property to alter layer properties, follow these steps:
Set up your document with whatever layer (or form or image) elements you want to use and change.
Select whichever object will trigger the behavior and choose Change Property from the Behaviors panel Actions list.
From the first pop-up menu, choose the tag of the object you want to change (<div>, <layer>, and so on). Unless you have changed the default, a layer in Dreamweaver will be created with the <div> tag.
The second pop-up menu will now be populated with all named instances of the chosen tag that appear in your document. From this menu, choose the specific instance you want to control. (Unlike Show-Hide Layers, you can control only one object with each occurrence of this behavior.)
Choose a target browser from the pop-up list on the third line of the dialog box. What you choose here will determine what choices will appear in the Property pop-up list to its left.
Choose a property to change. If the Property list is empty, the object you have chosen is not scriptable in the DOM of the browser you have targeted. If you want to change a property that isn't on the list, but that you know is scriptable, enter it by hand in the text field below.
Enter a new value for the property. It's up to you to choose a value acceptable for that property. The Change Property dialog box shown in Figure 17.29 is set to change the font-family of all text within the <div> layer named caption. If the value field for this dialog box didn't contain a valid font name, the property change would have no effect.
Because it's a generic behavior, with a very basic purpose, Change Property does not necessarily create cross-browser scripts. After you choose a target browser in the dialog box, the script will be entered using the syntax required for that browser. If all you're doing with the behavior is scripting form fields, your script will probably work across browsers because only basic DOM access is required for this kind of page element. If you're scripting layers, your behavior will definitely be browser-specific.
As discussed in Chapter 14, Netscape 4.x functions best if its proprietary <layer> tag is used to create layers, even though layers created with other tags will work there. If you target Netscape 4 in the Change Property behavior and specify that you want to change <div> layers, no scriptable properties will show up in the dialog box. If you choose the <layer> tag to change, however, you'll still be allowed to choose named instances of <div> layers, and the property list will supply a list of Netscape-formatted properties to change. Figure 17.29 shows this strange occurrence in action. This configuration will work fine in Netscape 4 or Netscape 6.
For some properties, it is possible to target IE and Netscape Navigator just by attaching two instances of Change Property to the same event handler. Figure 17.30 shows two separate configurations of the behavior, each set to change the vertical position of the specified layer on the page. Both behaviors are being applied to one text link, to be activated onClick. This strategy won't work with all properties. If you attempt to change the layer's background color in this way, for instance, IE interprets the Netscape syntax as a command to change the page's background color.