Workshop #3: Creating a More Complex ObjectBy now, you should be feeling at least a little bit comfortable with the API for creating Dreamweaver objects. So, it's time to get into some serious object scripting. This last workshop builds the most complex object yetone that requires a variety of form elements in its dialog box and requires a more complex return statement. You also add some short online help. note Warning This object includes some fairly advanced concepts. If you're new to scripting, you might want to skip this workshop for now and come back to it when you've had some more JavaScript practice. Sample Object: Inserting a Custom Horizontal RuleThis is a case in which Dreamweaver already provides an object to insert certain code, but you may not like the options the program gives you. Again, I start from my own workflow needs. The Dreamweaver Horizontal Rule object calls up no dialog box, although I can always use the Property inspector to set its properties. More important for me, though, the Property inspector won't let me set a color property for the tag. This wasn't an oversight on Macromedia's part; it was good, sound practice because only Internet Explorer supports this property, and, as noted previously, Dreamweaver encourages you to stick with cross-platform, cross-browser coding. But when I design web pages for intranets in which all the site visitors are using Internet Explorer, I want to be able to use colored rules. If I use the regular Horizontal Rule object, I have to use Code view or the Edit Tag command to enter the color property every time. It's definitely time for a custom object! Creating the Custom HR ObjectCreating this object follows the same basic procedure as the first two object workshops, but with the added complexity that the code inserted must be much more customizable and the dialog box interface will use more than just text fields for input. Task 1: Decide on the code to insert and how customizable it should be Where there's user input, there are lots of possibilities that have more to do with strategy than scripting. The <hr> tag can take several parameters in addition to color ( width , height , align , noshade , id ). Do we want to include all of them in our dialog box, or only some? If we include them all, and the user specifies only one or two, do we let the others revert to a default value, or do we eliminate them entirely? (Note that the <hr> tag has no required properties.) In keeping with good clean coding practice, thoroughness and a dose of probability, for the sample code here we'll include all the properties in the dialog box except id , which can be added later from the Property inspector if desired. All dialog box fields start out empty or at their default values. Unless the user enters a value for a property, the inserted code won't include that property. Thus, our custom object needs to be flexible enough to insert any code from <hr> to <hr width="50%" height="3" noshade align="center" color="#FF0000"> . Task 2: Design the form that collects the user input As well as determining what code should be inserted, it's always a good idea to know approximately what user interface (the dialog box) an object will have. For the new <hr> object, each possible property that users can add to the <hr> tag should be represented in the dialog box by a descriptive statement or label and an appropriate form input element to collect it: width (text field), height (text field), align (popup menu), noshade (checkbox), and color . If this were a regular HTML form, we'd probably use a text field for collecting color information. But the Dreamweaver API includes a custom form element: the color button. We'll follow the Dreamweaver program's own interface example in this, and use the color button along with a text field to allow users to enter the information however they choose. The desired layout for the dialog box is shown in Figure 2.13. Figure 2.13. The desired layout for the Custom HR object's dialog box.
Task 3: Create the basic object file As with the Block Spacer, creating this object is easiest if you start simple and add complexity as you go. Follow these steps:
<body> <form name="myForm"> <table border="0"> <tr valign="baseline"> <td align="right" nowrap > Width:</td> <td align="left" nowrap> <input type="text" name="width" size="8"> </td> <td align="right" nowrap>Height::</td> <td align="left" nowrap> <input type="text" name="height" size="8"> </td> <td nowrap align="right"> Align:</td> <td nowrap> <select name="align"> <option selected value="default">Default</option> <option value="left">Left</option> <option value="right">Right</option> <option value="center">Center</option> </select> </td> </tr> <tr valign="baseline"> <td align="right"> </td> <td align="left"> </td> <td nowrap align="right">No Shade:</td> <td align="left"> <input type="checkbox" name="noshade" value="noshade"> </td> <td align="right"> <input type="mmcolorbutton" name="colorswatch"> </td> <td > <input type="text" name="colorfield" size="10"> </td> </tr> </table> </form> </body> Task 4: Add an entry for the object to insertbar.xml So that the new Custom Horizontal Rule object displays properly in the Insert bar, open insertbar.xml in your text editor and add the following <button/> tag to your Development category: <button id="DW_Development_CustomHR" image="" enabled="" showIf="" file="Development\Custom HR.htm" /> Before proceeding to the next step, test the object out in Dreamweaver to make sure the dialog box displays properly. Of course, the dialog box is not functional yet. But it should display correctlyand clicking on the color button should even bring up the Dreamweaver color palette (see Figure 2.15). Figure 2.15. The dialog box for the Custom Horizontal Rule object, with working color button.
Task 5: Revise the objectTag() function to collect user input The tricky part about the Custom Horizontal Rule object is that, unlike the Block Spacer object, it contains conditional codeattributes for the <hr> tag that shouldn't be included unless the user enters values into the dialog box. This makes the task of constructing the objectTag() function's return statement a little bit different than it was in the previous workshop. This task is a challenge! Don't be frustrated if it takes you several tries to get it right.
Task 6: Use collected input to build the objectTag() function's return statement Now for the fun part: turning all this collected input into a complete <hr> tag for the return statement. The trick of creating an object like this, where the attributes are all optional and the user may or may not provide values for them, is that you don't want the code to include any properties not specified in the dialog box. After all, you don't want your <hr> tag to look like this: <hr width="" height="" color="" align=""> To ensure that only properties with values appear in the code, think of the code you're going to insert as a bunch of building blocks, like the illustration in Figure 2.16. Each attribute/value combination is a block; the opening and closing parts of the tag itself are blocks. The opening and closing blocks must always be present, but the interior blocks can be included or excluded based on which attributes you want to use. You're going to revise the objectTag() function so that it builds the <hr> tag one block at a time. You'll start with the opening block. Then, for each attribute, you'll determine whether the user has entered a value for that attribute and if he has, you'll add that block. When you're done, you'll tack on the closing block. Figure 2.16. The <hr> tag and its attributes, seen as individual building blocks of code.
Now all you need is some refining. Task 7: Refine the color input To follow the Dreamweaver interface standard for choosing colors, we should let our users choose whether to use the color button or the color text field to choose the color for the horizontal rule. We do this by linking the two fields so that no matter which entry method is used, both input elements will register the user's choice. (If the user types in a color name, the color button should display a swatch of that color; if he chooses a color from the button, the text field should display the name or hex number of that color. No matter which he chooses, the objectTag() function should collect the information.) To do this, we create two new functions and function calls for our object: a function that copies the value of the color text field into the color button, to be executed when the user has entered text in the text field; and a function that copies the value of the color button into the color text field, to be executed when the user chooses a color using the button.
Task 8: Refine the dialog box, and add some online help The Custom Horizontal Rule object is now fully functional and something to be proud of. It just needs a few extra touches on its interface to make it presentable to the world. Like the Block Spacer object in the previous workshop, this new object's dialog box should open with its focus in the first text fieldit needs initializing, in other words. And it could also use a sentence or two of online help, which can be added at the bottom of the dialog box.
Listing 2.6 Code for the Custom Horizontal Rule Object, Commented for Reference<html> <head> <! title shows in dialog box title bar > <title>Custom Horizontal Rule</title> <script language="JavaScript"> function objectTag() { //collect information from form/dialog box var widthValue = document.myForm.width.value; var heightValue = document.myForm.height.value; var noshadeValue = document.myForm.noshade.checked; var selected = document.myForm.align.selectedIndex; var alignValue = document.myForm.align.options[selected].value; var colorValue = document.myForm.colorswatch.value; //start with two building blocks var openingTag="<hr"; var closingTag=">"; //if user has entered a width, add the code for this attribute if (widthValue) { openingTag += ' width="' + widthValue + '"'; } //if user has entered a height, add the code for this attribute if (heightValue) { openingTag += ' size="' + heightValue + '"'; } //if user has chosen an alignment other than default, add the code for this attribute if (alignValue != "default") { openingTag += ' align="' + alignValue + '"'; } //if user has entered a color, add the code for this attribute if (colorValue) { openingTag += ' color="' + colorValue + '"'; } //if user has selected the noshade checkbox, add the code for this attribute if (noshadeValue) { openingTag += ' noshade '; } //assemble the building blocks return openingTag+closingTag; } //copy input from color text field to color button function setColorField() { document.myForm.colorfield.value = document.myForm.colorswatch.value; } //copy input from color button to color text field function setColorButton() { document.myForm.colorswatch.value = document.myForm.colorfield.value; } //put cursor in first text field when dialog box opens function initializeUI() { document.myForm.width.focus(); document.myForm.width.select(); } </script> </head> <body onLoad="initializeUI()"> <form name="myForm"> <table border="0"> <tr valign="baseline"> <td align="right" nowrap > Width:</td> <td align="left" nowrap> <input type="text" name="width" size="8"> </td> <td align="right" nowrap>Height:</td> <td align="left" nowrap> <input type="text" name="height" size="8"> </td> <td nowrap align="right"> Align:</td> <td nowrap> <select name="align"> <option selected value="default">Default</option> <option value="left">Left</option> <option value="right">Right</option> <option value="center">Center</option> </select> </td> </tr> <tr valign="baseline"> <td align="right"> </td> <td align="left"> </td> <td nowrap align="right">No Shade:</td> <td align="left"> <input type="checkbox" name="noshade" value="noshade"> </td> <td align="right"> <! if user chooses a new color, calls a function to copy color to text field > <input type="mmcolorbutton" name="colorswatch" onChange="setColorField()"> </td> <td > <! if user types in a new color name, calls a function to copy value to color button > <input type="text" name="colorfield" size="10" onBlur="setColorButton()"> </td> </tr> <tr valign="baseline"> <td align="right"> </td> <td align="left" colspan="5" bgcolor="#D3D3D3"> <p>To set width as percent, enter a percent sign in the width field; to set width as pixels, enter a number only. </p> <p>Note that the <color property is recognized by MSIE only.</p> </td> </tr> </table> </form> </body> </html> Task 9: Split the code into separate HTML and JS files Your Custom Horizontal Rule is finished! And what a lot of JavaScript code went into that object. If you want to follow the Macromedia example, for all but the simplest objects you'll separate your code into an HTML file and a linked JS file. In this task, you'll do that, so you can see how the HTML/JS file linking setup works.
note Troubleshooting What could go wrong? If you didn't link the two files correctly, Dreamweaver will report an error as soon as you try to choose the object, because it won't be able to find initializeUI() to initialize the dialog box. If you didn't quite copy and paste all the JavaScript code, Dreamweaver will report a JavaScript syntax error as soon as a function that wasn't moved successfully tries to execute. What can you do if this happens? Double-check the filename you entered as the src for the <script> tag. In the new JS file, double-check every function to make sure each ends with its very own curly brace. |