Creating General-Purpose UDFs


The functions in the FilmFunctions UDF library (refer to Table 22.4) are all related to the film concept, which is in turn somewhat related to the Films table in the ows database. As such, the library is really of interest only to the developers working on the Orange Whip Studios site. It's not going to be of much use to other ColdFusion developers.

It is, however, possible to create user-defined functions that have no ties to a particular application. You can think of such functions as general-purpose functions. They are useful for many different types of applications.

For instance, consider the javaScriptPopupLink() function used internally by the FilmFunctions library in Listing 22.4. That function isn't expecting any input that is specific to Orange Whip Studios or any other type of application. And its purposeto create pop-up windows easilymight come in handy in any Web-based application.

Things to Consider

You don't need to do anything special to create a general-purpose function. Go ahead and use the same <cffunction>, <cfargument>, and <cfreturn> syntax you have already learned about. Just bear these things in mind as you go along:

Keep the list of arguments as short as possible. ColdFusion will let you create UDFs with many, many arguments, but such functions quickly become unwieldy. If you feel you need to have lots of arguments, consider creating a CFML Custom Tag instead, as discussed in the next chapter.

Keep code reuse in mind. If the problem at hand has both an application-specific aspect and a general-purpose aspect, try to isolate the two parts of the problems in two different functions. For instance, the problem of displaying a pop-up window about a film has an application-specific aspect (the film) and a general-purpose aspect (the pop-up window). By creating two different functions, you can reuse the pop-up aspect in situations that don't have anything to do with films.

In Chapter 23, you will learn how to create your own Custom Tags and Components (CFCs) as well as functions. Custom Tags are significantly more powerful and flexible than custom functions. Try to use UDFs for simple matters, especially quick retrieval and formatting. Use Custom Tags and Components for more involved processes, especially those you can think of as discrete actions rather than simple "massaging."

Writing the SimpleJavaScriptFunctions Library

As an example of a general-purpose UDF library, let's consider the SimpleJavaScriptFunctions.cfm library we used earlier, in Listing 22.4. Presently, this library contains only one function, javaScriptPopupLink(), which is responsible for creating a link that opens a pop-up window when clicked. This function supports four arguments, as listed in Table 22.5.

Table 22.5. javaScriptPopupLink() Function Syntax

ARGUMENT

DESCRIPTION

linkURL

Required. The URL for the page that should appear in the pop-up window when the user clicks the link.

linkText

Required. The text of the linkthat is, the text the user will click to open the pop-up window. This text will also appear in the browser's status bar when the pointer hovers over the link.

popupWidth

Optional. The width of the pop-up window, in pixels. If this argument isn't provided, a default width of 300 is used.

popupHeight

Optional. The height of the pop-up window, in pixels. If this argument isn't provided, a default width of 200 is used.

popupTop

Optional. The vertical position of the pop-up window. If this argument isn't provided, a default value of 200 is used.

popupLeft

Optional. The horizontal position of the pop-up window. If this argument isn't provided, a default value of 300 is used.


NOTE

The popupWidth, popupHeight, popupTop, and popupLeft arguments correspond to the width, height, top, and left values supported by the JavaScript window.open() method. Consult a JavaScript reference for details


The function uses all these pieces of information to assemble the HTML code for an anchor element (that is, an <a href> tag) containing the appropriate JavaScript code to get the desired effect. The code is returned as the function's result (as a string).

Listing 22.6 is the ColdFusion code required to create javaScriptPopupLink().

NOTE

The goal here isn't to teach you about JavaScript (that would take a whole book in itself), but rather to show you how you can distill something like JavaScript code and package it into a UDF for your ColdFusion pages. The nice thing about this kind of abstraction is that people can use the UDF without needing to understand the JavaScript code it generates.


Listing 22.6. SimpleJavaScriptFunctions.cfmCreating a General-Purpose UDF
 <!---   Filename: SimpleJavaScriptFunctions.cfm  Created by: Nate Weiss (NMW)  Purpose: Creates a library of ColdFusion functions that   encapsulate JavaScript ideas ---> <!--- Function: JavaScriptPopupLink() ---> <!--- Returns an HTML link that opens a pop-up window via JavaScript ---> <cffunction name="javaScriptPopupLink" returnType="string" output="false">  <!--- One argument: FilmID --->  <cfargument name="linkURL" type="string" required="Yes">  <cfargument name="linkText" type="string" required="Yes">  <cfargument name="popupWidth" type="numeric" default="300">  <cfargument name="popupHeight" type="numeric" default="200">  <cfargument name="popupTop" type="numeric" default="200">  <cfargument name="popupLeft" type="numeric" default="300">  <!--- These variables are for this function's use only --->  <cfset var features = "">  <cfset var linkCode = "">  <!--- Window features get passed to JavaScript's window.open() command --->  <cfset features = "width=#ARGUMENTS.PopupWidth#,"  & "height=#ARGUMENTS.PopupHeight#,top=#ARGUMENTS.PopupTop#,"  & "left=#ARGUMENTS.PopupLeft#,scrollbars=yes">  <!--- Create variable called LinkCode, which contains HTML / JavaScript --->   <!--- needed to display a link that creates a pop-up window when clicked --->  <cfsavecontent variable="linkCode">  <cfoutput>  <a href="#ARGUMENTS.linkURL#"  onclick="  popupWin = window.open('#ARGUMENTS.linkURL#','myPopup','#features#');   popupWin.focus(); return false;"  onmouseover="window.status = '#JSStringFormat(ARGUMENTS.LinkText)#';return true;"  onmouseout="window.status = ''; return true;"  >#ARGUMENTS.LinkText#</a>  </cfoutput>  </cfsavecontent>  <!--- Return the completed link code --->   <cfreturn linkCode> </cffunction> 

NOTE

This listing includes some JavaScript code, such as window.open(), focus(), window.status, and return true. These are very basic JavaScript concepts. If you aren't familiar with them, consult any reference or online guide.


As with the earlier UDF examples in this chapter, the first thing this code does is define the function's arguments with the <cfargument> tag. This is actually the first UDF example that accepts more than one argument. As you can see, you can add as many arguments as you like. Just don't get totally carried away, since functions with dozens of arguments will probably be somewhat harder to use.

Next, a variable called features is created; this is the list of "window features" that will be supplied to the JavaScript window.open() method. You can find out more about how to specify window features in a JavaScript reference guide, but the basic idea is that this describes the physical pop-up window, including its position and size. When the function executes, the value of features will be something like this (depending on the actual arguments used):

 width=300,height=200,top=200,left=300,scrollbars=yes 

The next block of code uses the <cfsavecontent> tag to create a variable named linkCode. ColdFusion will process and evaluate all the code between the opening and closing <cfsavecontent> tags, then assign the final result to the linkCode variable. This makes it easier to create a variable that contains multiple lines, a variety of quotation marks, and so on. In this kind of situation, it's a lot easier than using the <cfset> tag. You can even use tags like <cfloop> within this type of block. That said, a <cfset> (or several <cfset> tags) would work equally well. The code might just be a bit harder to follow.

Within the <cfsavecontent> block, the basic idea is to generate a normal HTML <a> tag, with a normal href attribute. In addition to the href attribute, the <a> tag is also given onclick, onmouseover, and onmouseout attributes. These attributes contain JavaScript code that will execute when the user clicks the link, hovers over the link, and hovers away from the link, respectively.

NOTE

It is also necessary to use a pair of <cfoutput> tags here to force ColdFusion to evaluate the variables and expressions within this block. The final result (after all number signs (#), tags, and functions have been evaluated) is "captured" by <cfsavecontent> and placed into the linkText variable. See Appendix B for details.


The result is the behavior shown earlier in Figure 22.2: when the user clicks the link, a pop-up window appears. If the user's browser doesn't support JavaScript, or if scripting has been disabled, the Film Details page simply appears in the main window (as a normal link would). You can use your browser's View Source option to examine the final HTML and JavaScript code that gets sent to the browser.

Another Example Library: ColorFunctions

At this point, you know just about everything you need to know for creating user-defined functions with ColdFusion MX. Our companion volume, Advanced ColdFusion MX Application Development, has a chapter called "Advanced User-Defined Functions," which covers a few scenarios not discussed here. It also discusses creating UDFs with <cfscript> instead of the <cffunction> tag.

Now it's up to you to create the UDFs you need for your own applications!

Just to get your brain spinning, I have included the code for another general-purpose UDF library called ColorFunctions.cfm. This UDF library contains three functions, as listed in Table 22.6.

Table 22.6. Functions in the ColorFunctions UDF Library

FUNCTION

DESCRIPTION

listGetRand(list)

Picks one element at random from a list. This really doesn't have anything to do with colors; this library includes it so the randomColor() function can use it internally.

geTRandColor()

Returns a random hexadecimal color, in the form RRGGBB. The red, green, and blue portions of the color are each selected at random from the values 00 through FF, which ensures that the returned color is a member of the so-called browser safety palette and thus should display reasonably well on all monitors.

multicolorFormat(text)

Accepts any text (a sentence or paragraph, say) and returns the same text with HTML <font> tags wrapped around each word. Each of the <font> tags specifies that the word should be displayed in a color picked at random by the getrandColor() function.


Once you include this UDF library with a <cfinclude> tag, you could use any of these functions in your own templates. For instance, on a Web page, the following would display the message "Hello, World" in a random color:

 <cfoutput>  <div style="color:#getRandColor()#">Hello, World</div> </cfoutput> 

And this would display the following sentence about two cute forest critters, with each word colored randomly:

 <cfoutput>  #multicolorFormat("The quick red fox jumped over the lazy bear.")# </cfoutput> 

Listing 22.7 shows the <cffunction> code for the three functions listed above. The code for each of the individual functions is pretty simple. The purpose of this listing is to get you thinking about what kinds of operations UDFs can encapsulate. That said, you are invited to study this listing or adapt it to serve some other purpose. Refer to Appendix C, "ColdFusion Function Reference," for details about the listGetAt(), randRange(), and listLen(), functions used here.

Listing 22.7. ColorFunctions.cfmA Library of Functions Related to Colors
 <!---   Filename: ColorFunctions.cfm  Created by: Nate Weiss (NMW)  Purpose: Creates a library of user-defined functions  related to colors in the browser safety palette ---> <!--- Function: ListGetRandom() ---> <!--- Returns a random element from any comma-separated list ---> <cffunction name="listGetRand" output="false" returnType="string">  <!--- First argument: The comma-separated list --->  <cfargument name="list" type="string" required="Yes">  <!--- Second argument: List delimiter. Default to comma --->  <cfargument name="delim" type="string" required="false" default=",">    <cfreturn listGetAt(ARGUMENTS.list,   randRange(1, listLen(ARGUMENTS.list, ARGUMENTS.delim)), ARGUMENTS.delim)>  </cffunction> <!--- Function: GetRandColor() ---> <!--- Returns a random color in proper html color format ---> <cffunction name="getRandColor" output="false" returnType="string">  <!---   This is a list of hexidecimal values that can be used to specify colors  for use on Web pages. Any three of these can be combined to make a color,   in the form RRGGBB. For instance, 9900CC is a nice shade of purple.  --->  <cfset var hexList = "00,11,22,33,44,55,66,77,88,99,AA,BB,CC,DD,EE,FF">    <!--- Choose 3 of the Hex values randomly and return them all together --->  <cfreturn listGetRand(hexList) & listGetRand(hexList) & listGetRand(hexList)> </cffunction> <!--- Function: MulticolorFormat() ---> <!--- Adds <font> tags to any text such that each word is colored randomly ---> <cffunction name="multicolorFormat" output="false" returnType="string">  <!--- One argument: the text to make multicolored --->  <cfargument name="text" type="string" required="Yes">    <!--- This is what we will end up returning. Start with an empty string. --->  <cfset var string = "">  <cfset var word = "">    <!--- Loop through the list of words, treating spaces as list delimiters --->  <cfloop list="#ARGUMENTS.text#" index="word" delimiters=" ">  <!--- Create a <font> tag for this word, using a random color --->  <cfset string = string & ' <font color="#getRandColor()#">#word#</font>'>  </cfloop>    <!--- Return completed string --->   <cfreturn string>  </cffunction> 



Macromedia Coldfusion MX 7 Web Application Construction Kit
Macromedia Coldfusion MX 7 Web Application Construction Kit
ISBN: 321223675
EAN: N/A
Year: 2006
Pages: 282

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net