The following sections describe how you can use WDDX in ColdFusion applications. The first two sections describe the tools that ColdFusion provides for creating and converting WDDX. The remaining sections show how you use these tools for common application uses.
The cfwddx
tag can do the following conversions:
From |
To |
---|---|
CFML |
WDDX |
CFML |
JavaScript |
WDDX |
CFML |
WDDX |
JavaScript |
A typical cfwddx
tag used to convert a CFML query object to WDDX looks like the following:
<cfwddx action="cfml2wddx" input="#MyQueryObject#" output="WddxTextVariable">
In this example, MyQueryObject is the name of the query object variable, and WddxTextVariable is the name of the variable in which to store the resulting WDDX XML. Note
For more information on the cfwddx
tag, see CFML Reference.
The cfwddx
tag has a Validate
attribute that you can use when converting WDDX to CFML or JavaScript. When you set this attribute to True, the XML parser uses the WDDX DTD to validate the WDDX data before deserializing it. If the WDDX is not valid, ColdFusion generates an error. By default, ColdFusion does not validate WDDX data before trying to convert it to ColdFusion or JavaScript data.
The IsWddx
function returns True if a variable is a valid WDDX data packet. It returns False otherwise. You can use this function to validate WDDX packets before converting them to another format. For example, you can use it instead of the cfwddx
validate
attribute, so that invalid WDDX is handled within conditional logic instead of error-handling code. You can also use it to pre-validate data that will be deserialized by JavaScript at the browser.
ColdFusion provides two JavaScript objects, WddxSerializer
and WddxRecordset
, that you can use in JavaScript to convert data to WDDX. These objects are defined in the file webroot/cfide/scripts/wddx.js.
CFML Reference describes these objects and their methods in detail. The example "Transferring data from the browser to the server" shows how you can use these objects to serialize JavaScript to WDDX.
The following example demonstrates the transfer of a cfquery
recordset from a ColdFusion page executing on the server to a JavaScript object that is processed by the browser.
The application consists of four principal sections:
The following example uses the cfsnippets data source that is installed with ColdFusion:
<!--- Create a simple query --->
<cfquery name = "q" datasource ="cfsnippets"> SELECT Message_Id, Thread_id, Username, Posted FROM messages </cfquery> <!--- Load the wddx.js file, which includes the dump function ---> <script type="text/javascript" src="/CFIDE/scripts/wddx.js"></script> <script> // Use WDDX to move from CFML data to JavaScript <cfwddx action="cfml2js" input="#q#" topLevelVariable="qj"> // Dump the recordset to show that all the data has reached // the client successfully. document.write(qj.dump(true)); </script>
Note: To see how cfwddx
Action="cfml2js"
works, save this code under your webroot directory, for example in wwwroot/myapps/wddxjavascript.cfm, run the page in your browser and select View Source in your browser.
The following example serializes form field data, posts it to the server, deserializes it, and displays the data. For simplicity, it only collects a small amount of data. In applications that generate complex JavaScript data collections, you can extend this basic approach very effectively. This example uses the WddxSerializer JavaScript object to serialize the data, and the cfwddx
tag to deserialize the data.
The name appears in the Names added so far box.
The resulting WDDX packet appears in the WDDX packet display box. This step is intended only for test purposes. Real applications handle the serialization automatically.
The WDDX packet is transferred to the server-side processing code, which deserializes it and displays the information.
<!--- load the wddx.js file --->
<script type="text/javascript" src="/CFIDE/scripts/wddx.js"></script> <!--- Data binding code ---> <script> // Generic serialization to a form field function serializeData(data, formField) { wddxSerializer = new WddxSerializer(); wddxPacket = wddxSerializer.serialize(data); if (wddxPacket != null) { formField.value = wddxPacket; } else { alert("Couldn't serialize data"); } } // Person info recordset with columns firstName and lastName // Make sure the case of field names is preserved var personInfo = new WddxRecordset(new Array("firstName", "lastName"), true); // Add next record to end of personInfo recordset function doNext() { // Extract data var firstName = document.personForm.firstName.value; var lastName = document.personForm.lastName.value; // Add names to recordset nRows = personInfo.getRowCount(); personInfo.firstName[nRows] = firstName; personInfo.lastName[nRows] = lastName; // Clear input fields document.personForm.firstName.value = ""; document.personForm.lastName.value = ""; // Show added names on list // This gets a little tricky because of browser differences var newName = firstName + " " + lastName; if (navigator.appVersion.indexOf("MSIE") == -1) { document.personForm.names[length] = new Option(newName, "", false, false); } else { // IE version var entry = document.createElement("OPTION"); entry.text = newName; document.personForm.names.add(entry); } } </script> <!--- Data collection form ---> <form action="#cgi.script_name#" method="Post" name="personForm"> <!--- Input fields ---> Personal information<br> First name: <input type=text name=firstName><br> Last name: <input type=text name=lastName><br> <br> <!--- Navigation & submission bar ---> <input type="button" value="Next" onclick="doNext()"> <input type="button" value="Serialize" onclick="serializeData(personInfo, document.personForm.wddxPacket)"> <input type="submit" value="Submit"> <br><br> Names added so far:<br> <select name="names" size="5"> </select> <br> <!--- This is where the WDDX packet will be stored ---> <!--- In a real application this would be a hidden input field. ---> <br> WDDX packet display:<br> <textarea name="wddxPacket" rows="10" cols="80" wrap="Virtual"> </textarea> </form> <!--- Server-side processing ---> <hr> <b>Server-side processing</b><br> <br> <cfif isdefined("form.wddxPacket")> <cfif form.wddxPacket neq ""> <!--- Deserialize the WDDX data ---> <cfwddx action="wddx2cfml" input=#form.wddxPacket# output="personInfo"> <!--- Display the query ---> The submitted personal information is:<br> <cfoutput query=personInfo> Person #CurrentRow#: #firstName# #lastName#<br> </cfoutput> <cfelse> The client did not send a well-formed WDDX data packet! </cfif> <cfelse> No WDDX data to process at this time. </cfif>
The following simple example uses WDDX to store complex data, a data structure that contains arrays as a string in a client variable. It uses the cfdump
tag to display the contents of the structure before serialization and after deserialization. It uses the HTMLEditFormat
function in a cfoutput
tag to display the contents of the client variable. The HTMLEditFormat
function is required to prevent the browser from trying to interpret (and throwing away) the XML tags in the variable.
<!--- Enable client state management --->
<cfapplication name="relatives" clientmanagement="Yes"> <!--- Build a complex data structure ---> <cfscript> relatives = structNew(); relatives.father = "Bob"; relatives.mother = "Mary"; relatives.sisters = arrayNew(1); arrayAppend(relatives.sisters, "Joan"); relatives.brothers = arrayNew(1); arrayAppend(relatives.brothers, "Tom"); arrayAppend(relatives.brothers, "Jesse"); </cfscript> A dump of the original relatives structure:<br> <br> <cfdump var="#relatives#"><br> <br> <!--- Convert data structure to string form and save it in the client scope ---> <cfwddx action="cfml2wddx" input="#relatives#" output="Client.wddxRelatives"> The contents of the Client.wddxRelatives variable:<br> <cfoutput>#HtmlEditFormat(Client.wddxRelatives)#</cfoutput><br> <br> <!--- Now read the data from client scope into a new structure ---> <cfwddx action="wddx2cfml" input="#Client.wddxRelatives#" output="sameRelatives"> A dump of the sameRelatives structure <br> generated from client.wddxRelatives<br> <br> <cfdump var="#sameRelatives#">