Have you ever wondered how you could create JavaScript data from ColdFusion? Now before you say anything, I'm not talking about AJAX. While using AJAX to load data into the client is probably the most often used way to do this, it certainly isn't the only way. Consider the following example.

<cfset string= "Lindsey Lohan is a Cylon.">

<html>

<head> <cfoutput> <script> var data = '#string#' alert(data) </script> </cfoutput> </head>

<body> <h1>Demo</h1> </body> </html>

I've got a CFML variable, string, that I output within a script block. Because I'm working with a string, I surround the variable with single quotes. Double quotes would have worked as well. When run in the browser, the alert displays:

Woot. Nice and simple. Until someone goes and screws things up:

<cfset string= "Ray's neck is hurting today.">

This generates:

<script> var data = 'Ray's neck is hurting today.' alert(data) </script>

Ouch. Obviously you could just wrap the output in double quotes, but if my ColdFusion variable had both single and double quotes, I'm screwed. We could use the jsStringFormat function.

<cfset string= "Ray's neck is hurting today. He said, ""I need to take some pills.""">

<html>

<head> <cfoutput> <script> var data = '#jsStringFormat(string)#' alert(data) </script> </cfoutput> </head>

<body> <h1>Demo</h1> </body> </html>

Notice now my string has both single and double quotes embedded in the variable. The jsStringFormat function handles it perfect. Here is how it outputs the variable:

var data = 'Ray\'s neck is hurting today. He said, \"I need to take some pill.\"'

Again, I say woot. But that's just a string. How would you convert an entire ColdFusion query into a JavaScript variable? Or an array? Or a struct? How about a struct that contains an array that contains a query that... err you get the idea. Let's take a look at a ridiculous example:

<cfset addresses = []> <cfset addresses[1] = "403 Robinhood Circle, Lafayette, LA, 70508"> <cfset addresses[2] = "1801 Kaliste Saloom Rd, Lafayette"> <cfset addresses[3] = "400 Camellia Blvd, Lafayette, LA 70503">

<!--- Set of long/lats ---> <cfset longlats = []> <cfset longlats[1] = {lat=30.09,long=-91.9}> <cfset longlats[2] = {lat=30.08,long=-91.84}>

The code above generates an array of addresses, then an array of structures. ColdFusion provides us nice functions to introspect both arrays and structs (how do you think CFDUMP works?) so we could do this by hand, but luckily there is an even simpler solution: toScript. At it's simplest usage example, you provide it the data and the name of a JavaScript variable to create.

<cfoutput> <script> var #toScript(addresses,"addressesToPlot")# var #toScript(longlats,"locations")# </script> </cfoutput>

Which outputs:

<code> <script> var addressesToPlot = new Array(); addressesToPlot[0] = "403 Robinhood Circle, Lafayette, LA, 70508"; addressesToPlot[1] = "1801 Kaliste Saloom Rd, Lafayette"; addressesToPlot[2] = "400 Camellia Blvd, Lafayette, LA 70503";

var locations = new Array(); locations[0] = new Object(); locations[0]["lat"] = "30.09"; locations[0]["long"] = -91.9; locations[1] = new Object(); locations[1]["lat"] = "30.08"; locations[1]["long"] = -91.84;

</script>

Nice and simple, right? The docs mention that it supports strings, numbers, arrays, structs, and queries, but not CFCs. That's only partially true. You can pass a CFC to toScript, but it outputs broken code. This is what I got when I passed a CFC with two methods:

var apple = new Object(); apple["getfoo"] = apple["getentries"] =

It looks like it got the methods but didn't know what to do with them. Either way, hope this is useful.