| By Christian Schneider | Article Rating: |
|
| August 23, 2000 12:00 AM EDT | Reads: |
10,296 |
This article demonstrates how to write a paired custom tag that encapsulates complex DHTML logic into a simple-to-use tag. I was inspired to write by Tim Buntel's article about DHTML wrappers in CFDJ (Vol. 2, issue 4). It motivated me to extend a custom tag I had developed and used throughout my projects.
As you can see from Figures 1 and 2, my custom tag acts like a nice widget that enables Web pages to become user-friendly by providing a mechanism that collapses and expands content, then wraps it with a titled border. It groups Web sites into several sections that a user can expand and/or collapse. This kind of grouping is helpful when used in any kind of report that presents different sections.
Types of Custom Tags
The objective of ColdFusion's custom tags is to encapsulate complex code into an easy-to-use (and easy-to-reuse) interface. Basically, you can write three different types of (custom) tags: single, paired and nested parent–child. You've used each type when working with the usual ColdFusion tags:
- <cfinclude template="header.cfm">: A single CF tag that's useful for any kind of action that should be initiated
- <cfoutput> some content here </cfoutput>: The most popular paired CF tag, useful when working on the content included in your custom tag
- <cftree> <cftreeitem value="aSampleValue"> ... </cftree>: A good example of the nested parent–child variant, useful when working with hierarchical parent–child architectures; displays a hierarchical tree
Since my custom tag operates on content by wrapping it with an expand/collapse layer, it should definitely be developed as a paired custom tag. Basically all custom tags (no matter what type) have the ability to carry attributes, an important factor since custom tags should be as reusable as possible. For a custom tag to be reusable, developers must be able to affect and change what it does (for custom tags that encapsulate visual effects). But developers don't like using a lot of different attributes in a simple situation. To provide easy-to-use custom tags, consider making their attributes optional by providing default values for them when they're not used.
For this article's custom tag that wraps its content with a titled expand/collapse border, I made up a list of attributes that enables potential users to have as much control as possible. The following attributes are optional:
- Border="yes|no": Defines whether or not a visual border should be drawn (default: YES)
- BorderSize="size in px": Sets the size of the visual border in pixels (default: 3)
- BorderColor="color": Sets the color of the visual border to a named color or an #RGB value (default: lightgray)
- Image="image": Sets the image to use as the click-control
- ImageOpen="image": Sets the image to use when expanded
- Title="string": Sets the border's title
- TitleClosed="string": Sets a title to use when the layer is collapsed
- TitleTooltip="string": Sets the tooltip for the border's title
- TitleFont="font": Sets the font of the border's title (default: Arial)
- TitleColor="color": Sets the color of the border's title (default: the page's default text color)
- TitleColorOpen="color": Sets the color of the border's title when the layer is expanded (default: the same title color you set previously)
- TitleSize="size in pt": Sets the size of the border's title (default: 10)
- IsClosed="yes|no": Defines whether the layer should be initially collapsed or expanded (default: no)
- Width="width in px or %": Sets the width of the layer as an absolute pixel value or as a percentage (default: 100%)
I've shown what this custom tag is intended for and what attributes it can take. Here's an example of how to use it:
<cf_openLayer title="My Test" bordercolor="Red">
This content can be made of anything... Put HTML, CFML,
Applets, Images and even other nested instances of this
custom tag here...
</cf_openLayer>
This simple example generates a red expand/collapse border titled "My Test" around the content. All other attributes not specified here are initialized with their default values inside the custom tag's code.
Now for the Dirty Part
So far I've demonstrated what the custom tag does and how to use it. This is enough for developers who don't like to get in touch with the code inside the custom tag but merely want to use the effect on their pages. This encapsulation is the main reason custom tags are so widespread and have gained such broad acceptance in the developer community – ease of use without concern for the inside details.
For those who'd like to go inside, I'll explain briefly how the dirty part – the DHTML code to generate the effect of expanding/collapsing content – was done. In Internet Explorer the visual effect of expanding and collapsing content using DHTML is made possible by the DOM (Document Object Model), which makes every HTML tag with its styles and properties transparently accessible to the developer. I can easily change the style of the layer holding the content from expanded to collapsed and vice versa. In Netscape, which doesn't have a DOM, this isn't as easy to achieve. Instead, Netscape makes HTML dynamic by making certain properties of layers accessible. I can change the layers' position and content, and even show and hide them, but I can't collapse them to free the space. Okay, it actually can be done, but with a completely different approach: dynamically rewriting the Web page's HTML code with JavaScript. Since this would break the handy way to incorporate it into a custom tag to use anywhere on a page (even multiple times, and even nested), this article's custom tag is made especially for Internet Explorer. "Hey, what about all the other browsers? If they can't produce the effects, please don't let them crash with JavaScript errors...." As this statement was the first thing that came into my mind, I made it browser-safe using ColdFusion. Using ColdFusion? Yes, that's possible. It's a convenient (and safe) way to make any kind of client-side effects browser-safe; ColdFusion's built-in variable #CGI.HTTP_USER_AGENT# sniffs out what browser the client is accessing the current template with. Using this variable, the custom tag checks whether the client is using Internet Explorer 4 (or higher) or any other browser and stores this in a Boolean variable, which is used to dynamically send different code to the client: either the full-blown DHTML and JavaScript code, or – if accessed with another browser – simple HTML code.
As mentioned above, all types of custom tags can carry attributes. These attributes (like those in the sample snippet above) are accessible inside the custom tag's code via the ATTRIBUTES variable scope, which holds all attributes and their values like a structure. The two attributes in the sample above can be accessed inside the custom tag using #ATTRIBUTES.title# and #ATTRIBUTES.bordercolor#, respectively. By using <cfparam> you can make attributes optional by providing them with default values as in this statement:
<cfparam name="ATTRIBUTES.bordersize" default="3">
This is used inside the custom tag to set the default border size to three pixels if a size wasn't provided.
By accessing the content that's wrapped by the starting and closing tags, I can make a custom tag into a paired custom tag. To put it simply, all the content that the starting and closing tags wrap inside is stored in the variable #THISTAG.GeneratedContent#, which can be manipulated depending on what you wish your custom tag to do. THISTAG is a special structure holding information for custom tags regarding the way they were called. To check whether the paired custom tag is used correctly (meaning it actually has an ending tag), look in the Boolean variable #THISTAG. HasEndTag# would be true if the custom tag were called with an ending tag provided and false if not. This valuable information should be checked first in all paired custom tags so they can stop executing and throw an exception when the user has forgotten to use the closing tag.
The THISTAG structure provides you, the developer of custom tags, with interesting information: the string in #THISTAG.ExecutionMode# is either START or END depending on whether the starting or closing tag is being processed. Using this mode flag, you can write paired custom tags that do some work when the starting tag is processed, and more when the closing tag is processed. I coded my custom tag that way: at the processing of the starting tag it opens the titled border as a layer and draws the click-control with which the users can expand and collapse the content. At the processing of the ending tag it simply closes the layer and its border (see Listing 1).
Another interesting thing in this custom tag's code is the JavaScript for expanding and collapsing the layer holding the wrapped content. The effect is achieved by assigning either "none" or "block" as the value of the current layer's "display" style property. What makes it so interesting is that you can use the custom tag as often as you want on one page, because it assigns each layer a randomly generated, unique ID that's used to address each layer separately. The general JavaScript code used to generate the effect is put out on the page only once. This is made possible by storing a special flag in the REQUEST variable scope when the JavaScript code is written on the page for the first time. This flag is checked for every subsequent instance of this custom tag on the requested page. As the name might suggest, the REQUEST variable scope is available for all files (included files, custom tag, and more) for the current request accessing the page. That way the custom tag can check whether it was already used on the current requested page. If it was, it only needs to draw the layer and doesn't need to write redundant JavaScript code.
I hope my brief explanation of how this custom tag works inside and what techniques were used is sufficient. Unfortunately, showing all the details of the DHTML effect is beyond the scope of this article.
VTML Please
Wow! Besides HTML, DHTML, CFML, XML and WML, there's still room for another -ML abbreviation: VTML (Visual Tools Markup Language), the great family of markup languages that customize Allaire's ColdFusion Studio. The wonderful thing about VTML is that it's derived from XML, so you can easily get started based on your existing knowledge of tag-based markup languages. Using VTML you can control all the helpful things Allaire made available in ColdFusion Studio – Tag Inspector, Tag Insight, Tag Editing Dialogs, CF Studio Wizards and more. It's helpful for custom tag developers, since it enables them to tightly integrate their tags into the ColdFusion Studio IDE. It's easy to do: simply provide the article's custom tag with a VTML file for ColdFusion Studio's Tag Insight. I'm sure every developer working with Studio is using the Tag Insight feature (enabled from the Settings Dialog) quite often while typing HTML and CFML tags. It's the handy popup box that lists all possible attributes of the tag you're currently typing. In addition to making this kind of integration with Studio possible, Allaire has taken another step forward by providing us with visual tools for the VTML development inside Studio. As you can see from Figure 3, the visual VTML editor for the Tag Insight can be called from the Resource Tab's Tag Inspector (click on the red marked icon). To generate a Tag Insight for your custom tag in the VTML editor:
- Click on the Add Tag... button and enter the custom tag's name (here CF_openLayer).
- Click the Add... button on the right tab to add attributes to your custom tag.
- Define the type of each attribute by choosing the appropriate one from the Edit Type drop-down listbox:
- Text: For attributes taking strings as their value
- Enumerated: For attributes taking one of a list of predefined values
- Color: For attributes representing a color value
- Font: For attributes representing a font definition
- FileName: For attributes holding a file name
- FilePath: For attributes holding a file path
- Directory: For attributes holding a directory name
- RelativePath: For attributes holding a relative path
- Style: For attributes holding a style definition
- Flag: For attributes acting as flags
- Click the Done button and restart ColdFusion Studio.
- Open a new template and start typing <cf_openLayer>, then try to set some attributes. Voilà! Tag Insight is working for this custom tag.
What about the VTML? That was done by the VTML editor. If you're curious, Listing 2 provides exactly what the VTML editor has generated. After using the editor, you can also find this file on your workstation in the subdirectories of C:\Program Files\Allaire\ColdFusion Studio\Extensions\TagDefs\, depending on where you installed ColdFusion Studio. You can distribute this VTML file along with your custom tag to enable developers using your tag to seamlessly integrate it into Studio.
While writing this article I submitted this custom tag and its VTML file to Allaire's Tag Gallery ( www.allaire.com/developer/gallery.cfm), so you can download it from there. Watch for updated and enhanced versions.
Published August 23, 2000 Reads 10,296
Copyright © 2000 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Christian Schneider
Christian Schneider is an Allaire Certified ColdFusion and Web site developer. He has over four years of intensive experience developing CF-based intranet applications for banks and logistic corporations.
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Betas Target RIAs and Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe Fiddles with its Web Apps
- Adobe & Salesforce Cut Cloud Deal
- Hosting.com Launches ColdFusion 9 in the Cloud
- The Real Time Infrastructure Ultimatum
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Is Microsoft as Free as Open Source?
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF




















