Welcome!

You will be redirected in 30 seconds or close now.

ColdFusion Authors: Yakov Fain, Jeremy Geelan, Maureen O'Gara, Nancy Y. Nee, Tad Anderson

Related Topics: ColdFusion

ColdFusion: Article

Server to Client WDDX

Server to Client WDDX

The Web Distributed Data Exchange (WDDX) is an XML-based technology that allows different Web technologies to exchange data. One function of WDDX is to send ColdFusion queries to JavaScript for use on the client. This article details how to use this functionality with HTML SELECT statements, and assumes you're familiar with ColdFusion and HTML forms but not with WDDX and JavaScript.

WDDX, HTML forms, ColdFusion queries and JavaScript are combined to create a single page providing SELECT statements that are dynamically populated. In addition, one SELECT statement can be filled based on an earlier user selection on the same Web page. In essence, this makes queries that were traditionally available only on the server side now available on the client.

ColdFusion and HTML forms can be used together to dynamically populate SELECT controls from a ColdFusion query. When a user views this form, the query is performed; the SELECT statement contains the latest options from the table that was queried. To enhance this process you may want to populate a second SELECT statement based on a selection the user made from an earlier one. For instance, the first SELECT statement offered options for Colors and Trees (see Figure 1).

If the user selected Colors from the first SELECT control, the second will be populated with the options green, orange and red (see Figure 2).

If the user selected Trees, then the second SELECT will be populated with the options Fir, Hemlock and Pine (see Figure 3).

A common way to implement this behavior is on two separate pages since the first selection wouldn't be known until the user submitted the form. This article shows how to pass the second set of options to the client so the process can take place on a single page.

The first step in implementing this process is the conversion of a ColdFusion query to a JavaScript array (technically, the query is converted into a JavaScript recordset structure). Since you don't know which option a user will select from the first SELECT statement, you'll have to pass all queries that may be needed for options in the second SELECT statement. To do this you'll use WDDX.

WDDX allows you to exchange data between ColdFusion and JavaScript. The following steps are necessary:

1. Perform a ColdFusion query.
2. Use WDDX to convert the query into a JavaScript array.
3. Place the JavaScript array definition in the JavaScript section of the page.

You may then use the data as you would a JavaScript array.

Step 1, performing queries, is familiar to any ColdFusion developer. For this example consider two queries - qryColor and qryTree. Each query reads three rows of data containing a primary key value, a color name or primary key value, and a tree name.

Step 2 uses WDDX to convert the ColdFusion queries to JavaScript usable variables. This is a two-step process, but we'll use a shortcut and make it a one-step process. You need to convert the ColdFusion query into a WDDX packet, then convert the packet into a JavaScript variable. This process uses the <CFWDDX> tag. Without using the shortcut the two lines of code are:

<CFWDDX ACTION="CFML2WDDX"
INPUT="#qryTree#"
OUTPUT="jsTreeTemp">

<CFWDDX ACTION="WDDX2JS"
INPUT="#jsTreeTemp#"
TOPLEVELVARIABLE="jsTreeTLV"
OUTPUT="jsTree">

The first statement uses the attribute ACTION="CFML2WDDX". This converts or, in WDDX lingo, serializes the ColdFusion query into a WDDX packet stored under the name jsTreeTemp. It isn't necessary to understand the actual contents of the packet in order to use it, but, for the curious, see Listing 1 for the query containing the tree primary keys and names converted to WDDX. The indentation used in the packet is for readability only; the actual packet output contains no line breaks.

The second statement uses the ACTION="WDDX2JS" attribute to change the WDDX packet to a JavaScript variable, i.e., deserializes from WDDX to JavaScript. The actual variable type is defined in a file named wddx.js that you'll reference on the page that's installed with ColdFusion. In the code for this page the reference looks like:

<SCRIPT TYPE="text/javascript"
LANGUAGE="JavaScript"
SRC="/CFIDE/scripts/wddx.js">
</SCRIPT>

If this isn't included, you'll probably see an error:

'WddxRecordset' is undefined.

The input for the tag is the WDDX packet created in the first CFWDDX tag. The OUTPUT attribute holds the definition of the JavaScript variable that we'll use in the JavaScript section of the code. The TOPLEVELVARIABLE attribute defines the name of the variable to be used in the JavaScript code.

You need only one tag to perform both these steps using the CFWDDX tag:

<CFWDDX ACTION="CFML2JS"
INPUT="#qryTree#"
TOPLEVELVARIABLE="jsTreeTLV"
OUTPUT="jsTree">

This converts the ColdFusion query directly into the JavaScript variable and Step 2 is completed.

Step 3 is quite simple. You simply need to start the script section of the page using:

<SCRIPT LANGUAGE="JavaScript">

and then use CFOUTPUT to put the JavaScript variable definitions into the script section of the page. When you use the code:

<CFOUTPUT>#jsTree#</CFOUTPUT>

you place the JavaScript variable definition on the page. As with the actual format of the WDDX, it's not essential to understand the format of the variable declaration. But again, for the curious, the qryTree query becomes the JavaScript variable defined by:

jsTreeTLV=new WddxRecordset();
_t2=new Array(); _t2[0]=1;_t2[1]=3;_t2[2]=2;
jsTreeTLV.tree_id=_t2;_t2=new
Array();_t2[0]="Fir";_t2[1]="Hemlock";_t2[2]="Pine";
jsTreeTLV.tree_name=_t2;_t0=null;_t1=null;_t2=null;

In the actual code there are no line breaks, just as in the WDDX packet.

To help you understand how to use this definition, think of the query being converted into an array of the general form TopLevelVariableName.columnname[i]. Specifically, the query qryTree generates:

jsTreeTLV.tree_id[0]=1 (the primary key value) and
jsTreeTLV.tree_name[0]=Fir,
jsTreeTLV.tree_id[1]=3 (the primary key value) and
jsTreeTLV.tree_name[1]=Hemlock,
jsTreeTLV.tree_id[2]=2 (the primary key value) and
jsTreeTLV.tree_name[2]=Pine.

Since JavaScript is case sensitive, it's important to note that in the deserialization process the TOPLEVELVARIABLE attribute value of the CFWDDX tag keeps its case, and the field names from the query become lowercase; the case of the columns from the query doesn't matter. Note that the index for the array starts at 0 and not 1.

With the ColdFusion queries converted into JavaScript variables, it's time to look at the JavaScript that uses these variables.

The goal of the page now is to make these events occur:

1. When the user selects an option from the Select1 form control, a JavaScript function called choosenext() is called.

2. The choosenext() function decides which option the user selected.

3. The choosenext() function fills the DynamicSelect form control with the appropriate query information passed into the JavaScript.

To accomplish Step 1, a SELECT statement is created with the form using HTML:

<SELECT NAME="Select1" onChange=choosenext()>

The statement uses the JavaScript onChange event handler. This means that when a selection is made from the SELECT box, an event occurs (onChange) and the function called choosenext() is called (defined in the SCRIPT section of the page). This happens as soon as the user makes a change in the SELECT statement before the form is even submitted.

The job of the choosenext() function is to populate the SELECT statement that was created with HTML:

<SELECT NAME="DynamicSelect">
<OPTION VALUE="">
</OPTION>
</SELECT>

Nonbreaking spaces are used because Navigator won't dynamically enlarge the width of the box, but if this isn't done the options won't display correctly .

Now Step 2 needs to be completed, i.e., deciding which selection was made in the Select1 form control. This can be done by using the JavaScript "if" statement in the form.

if (document.TestForm.Select1.selected
Index==0)
if (document.TestForm.Select1.selected
Index==1)
if (document.TestForm.Select1.selected
Index==2)

This statement takes advantage of the Document Object Model (DOM). The document object is the entire page with the "TestForm" form that contains the "Select1" SELECT control. This object, which can be referenced by the name "document.TestForm.Select1", has a property called selectedIndex. Then it's all put together to see which option the user chose from the SELECT control and guides the program flow into the appropriate section of the choosenext() function.

Now it's time to get Step 3 done: filling the "DynamicSelect" SELECT control with the needed query results (which, as you recall, have been converted into JavaScript variables). First you need to delete any options in the SELECT control by setting the number of options to 0. Again, we need to take advantage of the DOM and use the code:

document.TestForm.DynamicSelect.
length=0;

This sets "DynamicSelect's" length to 0. All SELECT controls have a length property just as they have a selectedIndex property, which we used earlier.

Next, a loop will be used to put the correct number of options into the SELECT statement. The number of times to loop will be determined by the statement:

for (var RowNum=0; RowNum<jsTreeTLV.tree_id.length; RowNum++)

This creates a loop counter called RowNum that starts at 0 since the index of the array starts at 0. The loop will stop when RowNum exceeds the length of the array, which is equivalent to the number of records read in the ColdFusion query. This number is retrieved from a property of a JavaScript array called length and is referenced by the code:

jsTreeTLV.tree_id.length

The last part of the loop statement, RowNum++, increments RowNum by one each time through the loop.

Finally, the code that creates the options and puts them into the DynamicSelect form control is used. To accomplish this we use the following lines of code:

NewOpt=new Option;
NewOpt.value=jsColorTLV.color_id
[RowNum];
NewOpt.text=jsColorTLV.color_name[RowNum];
document.TestForm.DynamicSelect.
options[RowNum]=NewOpt;

Each time through the loop a new option is created using the JavaScript operator new. This creates a new instance of an option to be placed within the SELECT control. Then the option needs to be given a value for the VALUE attribute and text to be displayed to the user. This is accomplished using the code:

NewOpt.value=jsColorTLV.color_id
[RowNum];
NewOpt.text=jsColorTLV.color_name[RowNum];

This code uses the DOM and the value and text properties of the options, which is itself a property of the SELECT statement. Each time through the loop the next values from the JavaScript array are taken and assigned to an option. The last line of code:

document.TestForm.DynamicSelect.
options[RowNum]=NewOpt;

assigns the new option created to the list of previous options. The options property is actually an array that holds the options. That's why the loop will generate code that will fill the array using options[0], options[1], options[2], etc.

Just before the choosenext() function is exited, the DynamicSelect statement needs to have the first option selected so it'll appear in the list of options. Otherwise a blank option will be used. This is done with the code:

document.TestForm.DynamicSelect.
options[0].selected = true;

This code makes another reference to the DOM and sets the Boolean property selected (of the options property) to true. This puts the first option in the SELECT control. Remember that the first element of the array has an index of zero.

With the selection of an option from the first SELECT control, the second SELECT control is dynamically populated.

More Stories By Matthew Boles

Matthew Boles has been doing ColdFusion training for Allaire for nearly two years and has worked with ColdFusion since version 1.5. He is also a certified Novell and Microsoft instructor, although he now devotes his professional time to ColdFusion training and consulting. [email protected]

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
René Bostic is the Technical VP of the IBM Cloud Unit in North America. Enjoying her career with IBM during the modern millennial technological era, she is an expert in cloud computing, DevOps and emerging cloud technologies such as Blockchain. Her strengths and core competencies include a proven record of accomplishments in consensus building at all levels to assess, plan, and implement enterprise and cloud computing solutions. René is a member of the Society of Women Engineers (SWE) and a m...
Early Bird Registration Discount Expires on August 31, 2018 Conference Registration Link ▸ HERE. Pick from all 200 sessions in all 10 tracks, plus 22 Keynotes & General Sessions! Lunch is served two days. EXPIRES AUGUST 31, 2018. Ticket prices: ($1,295-Aug 31) ($1,495-Oct 31) ($1,995-Nov 12) ($2,500-Walk-in)
Andrew Keys is Co-Founder of ConsenSys Enterprise. He comes to ConsenSys Enterprise with capital markets, technology and entrepreneurial experience. Previously, he worked for UBS investment bank in equities analysis. Later, he was responsible for the creation and distribution of life settlement products to hedge funds and investment banks. After, he co-founded a revenue cycle management company where he learned about Bitcoin and eventually Ethereal. Andrew's role at ConsenSys Enterprise is a mul...
Nicolas Fierro is CEO of MIMIR Blockchain Solutions. He is a programmer, technologist, and operations dev who has worked with Ethereum and blockchain since 2014. His knowledge in blockchain dates to when he performed dev ops services to the Ethereum Foundation as one the privileged few developers to work with the original core team in Switzerland.
Digital Transformation and Disruption, Amazon Style - What You Can Learn. Chris Kocher is a co-founder of Grey Heron, a management and strategic marketing consulting firm. He has 25+ years in both strategic and hands-on operating experience helping executives and investors build revenues and shareholder value. He has consulted with over 130 companies on innovating with new business models, product strategies and monetization. Chris has held management positions at HP and Symantec in addition to ...
The challenges of aggregating data from consumer-oriented devices, such as wearable technologies and smart thermostats, are fairly well-understood. However, there are a new set of challenges for IoT devices that generate megabytes or gigabytes of data per second. Certainly, the infrastructure will have to change, as those volumes of data will likely overwhelm the available bandwidth for aggregating the data into a central repository. Ochandarena discusses a whole new way to think about your next...
CloudEXPO | DevOpsSUMMIT | DXWorldEXPO are the world's most influential, independent events where Cloud Computing was coined and where technology buyers and vendors meet to experience and discuss the big picture of Digital Transformation and all of the strategies, tactics, and tools they need to realize their goals. Sponsors of DXWorldEXPO | CloudEXPO benefit from unmatched branding, profile building and lead generation opportunities.
Dynatrace is an application performance management software company with products for the information technology departments and digital business owners of medium and large businesses. Building the Future of Monitoring with Artificial Intelligence. Today we can collect lots and lots of performance data. We build beautiful dashboards and even have fancy query languages to access and transform the data. Still performance data is a secret language only a couple of people understand. The more busine...
All in Mobile is a place where we continually maximize their impact by fostering understanding, empathy, insights, creativity and joy. They believe that a truly useful and desirable mobile app doesn't need the brightest idea or the most advanced technology. A great product begins with understanding people. It's easy to think that customers will love your app, but can you justify it? They make sure your final app is something that users truly want and need. The only way to do this is by ...
DXWorldEXPO LLC announced today that Big Data Federation to Exhibit at the 22nd International CloudEXPO, colocated with DevOpsSUMMIT and DXWorldEXPO, November 12-13, 2018 in New York City. Big Data Federation, Inc. develops and applies artificial intelligence to predict financial and economic events that matter. The company uncovers patterns and precise drivers of performance and outcomes with the aid of machine-learning algorithms, big data, and fundamental analysis. Their products are deployed...