It's easy in Dreamweaver 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 before version 7.
The Basics of Dragging and Dropping
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 14.17 shows the Drag Layer behavior dialog box.
Figure 14.17. The Drag Layer behavior dialog box in Basic and Advanced modes.
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.
Constraining the Drag Area
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 out these values can be simple or 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 constrain, and write down its starting L (left) and T (top) positions .
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 your "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 value from the larger one. Figure 14.18 shows a form you might find handy for your note taking.
Figure 14.18. A form for determining constraint values in the Drag Layer dialog box.
Assigning a Drop Target (and Snapping to It)
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 1 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 buttonclick the button, and the current coordinates of the draggable layer are 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.)
Specifying a Drag Handle
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 (such as 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 miniwindow or pop-up 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 the 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 14.19):
Figure 14.19. Using a temporary layer to determine measurements for a drag handle.
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.
Changing the Z-Index
The z-index determines which layers are on top of which other layers. While a layer is being dragged, it should probably be on topdragging 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 14.3. Creating a Draggable Shopping Cart Interface
In this exercise, you use the Drag Layer behavior to create a graphic shopping experience in which visitors can drag shopping bags into a cart. All the files for this exercise can be found on the book's website in the chapter_14/shoppingcart folder.
Start by opening shopping.html and examining its contents (see Figure 14.20). All the page elements are in place, and the layers have been given descriptive names . None of the scripting has been added.
Figure 14.20. The shopping.html file, ready for adding behaviors.
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 14.21 shows the editing dialog box for the redbag layer, with appropriate values entered.
Figure 14.21. The Drag Layer dialog box for the redbag layer, showing its correct constraint values.
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 14.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.
Figure 14.22. The desired location of all three shopping bags after they're dropped in the cart.
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 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! 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 windowbut not outside your official shopping rectangle.
Triggering Actions with Drag and Drop
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
Figure 14.23. The Drag Layer dialog box, configured to open an alert window with the "Hello world" message if the layer is dropped on target.
Another handy oneliner 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.
Using Drag Layer to Trigger Another Behavior
Figure 14.24. Borrowing the function call from the Pop-up Message behavior to use in the Drag Layer dialog boxthe Pop-up Message behavior will be executed when the dragged layer is dropped.
Exercise 14.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_14/shoppingcart folder on the book's website. Whichever file you open, save it as buying.html .
window.alert('You bought me!')
This nice, simple statement makes a pop-up 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 in your browser. Dragging the bag to the cart should call up a pop-up window like the one shown in Figure 14.25.
Figure 14.25. Dragging a shopping bag to the cart, and the resulting alert window.
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, 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, blueprice) 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 14.26 shows this happening.
Figure 14.26. Creating a simple text link as a temporary holder for a function call.
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 textincluding its <a> tag, event handler, and function callshould 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):
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 14.27.
Figure 14.27. The Drag Layer dialog box showing the pasted function call from the Show-Hide Layers behavior.
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 14.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 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. All three of your shopping bags should now be scripted.
Aren't you glad you gave your layers easy-to-remember names such as 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 disappears; if you drop it in the cart, the price reappears. (If you get stuck, buying_finished.html contains the completed exercise.)