Using WDDX



ColdFusion provides several tools for creating and converting WDDX that you can use for common application uses.

Using the cfwddx tag

The 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 thecfwddx tag, see the CFML Reference.

Validating WDDX data

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 cfwddxvalidate 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 JavaScript at the browser deserializes.

Using JavaScript objects

ColdFusion provides two JavaScript objects, WddxSerializer object and WddxRecordset object, that you can use in JavaScript to convert data to WDDX. These objects are defined in the file webroot/cfide/scripts/wddx.js.

The 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.

Converting CFML data to a JavaScript object

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:

  • Running a data query

  • Including the WDDX JavaScript utility classes

  • Calling the conversion function

  • Writing the object data in HTML

The following example uses the cfdocexamples data source that is installed with ColdFusion:

<!--- Create a simple query ---> 
<cfquery name = "q" datasource ="cfdocexamples"> 
    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 web root directory, for example in wwwroot/myapps/wddxjavascript.cfm, run the page in your browser and select View Source in your browser.

Transferring data from the browser to the server

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 effectively. This example uses the WddxSerializer JavaScript object to serialize the data, and the cfwddx tag to deserialize the data.

Use the example

  1. Save the file under your web root directory, for example in wwwroot/myapps/ wddxserializedeserialze.cfm.

  2. Display http://localhost/myapps/wddxserializedeserialze.cfm in your browser.

  3. Enter a first name and last name in the form fields.

  4. Click Next.

    The name appears in the Names added so far box.

  5. Repeat steps 3 and 4 to add as many names as you wish.

  6. Click Serialize to serialize the resulting data.

    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.

  7. Click Submit to submit the data.

    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> 
     
    <!--- The WDDX packet is stored here.---> 
    <!--- In a real application this text area 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>

Storing complex data in a string

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> 
 
<!--- Now read the data from client scope into a structure ---> 
<cfwddx action="wddx2cfml" input="#Client.wddxRelatives#" output="sameRelatives"> 
<br> 
A dump of the sameRelatives structure generated from client.wddxRelatives<br> 
<cfdump var="#sameRelatives#">