One of the cool new features of ColdFusion 9 is CFaaS, or ColdFusion as a Service. I'll be honest, I hate the abbreviation. It makes me think of a disease. But - I'll get over it since the feature itself is so impressive. During the ColdFusion Meetup (recording here), ColdFusion Evangelist Terry Ryan demonstrated using CFDOCUMENT remotely via Flex. In his demo, he enters some text, clicks a button, and gets the URL to download a PDF. This reminded me that many moons ago, earlier in the ColdFusion 9 beta, I had created a simple demo called DeadBike. (I'll buy you a beer at CFUNITED if you can guess why.) Here is a quick video showing it in action (clicking will take you to a full screen view, so I'd recommend 'open in new tab'):
So the code behind this is very similar to what Terry showed. Note that I've been lazy and hard coded all the security information within Flex.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:cf="coldfusion.service.mxml.*" layout="absolute" viewSourceURL="srcview/index.html">
<cf:Config id="conf" cfServer="127.0.0.1" cfPort="8502" serviceUserName="service" servicePassword="service" />
<cf:Document id="doctestnow" action="generate" format="pdf" result="handleResult(event)" fault="handleError(event)" />
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
public var res:String = new String();
private function renderSourceAsPDF():void {
var source:String = sourceText.text;
if(source.length == 0) return
doctestnow.content = source;
doctestnow.execute();
}
private function handleResult(event:ResultEvent):void {
res=event.result.toString();
pdfviewer.location=res;
}
private function handleError(event:Event):void {
mx.controls.Alert.show(event.toString());
}
]]>
</mx:Script>
<mx:HDividedBox width="100%" height="100%">
<!-- source side -->
<mx:VBox width="50%" height="100%">
<mx:Panel title="Source" width="100%" height="100%">
<mx:TextArea id="sourceText" width="100%" height="100%" />
</mx:Panel>
<mx:HBox horizontalAlign="right" width="100%">
<mx:Button label="Render PDF" click="renderSourceAsPDF()" />
</mx:HBox>
</mx:VBox>
<!-- render side -->
<mx:Panel title="PDF" width="50%" height="100%">
<mx:HTML id="pdfviewer" width="100%" height="100%" />
</mx:Panel>
</mx:HDividedBox>
</mx:WindowedApplication>
Let's focus on the interesting bits first. You can find the connection/service information here:
<cf:Config id="conf" cfServer="127.0.0.1" cfPort="8502" serviceUserName="service" servicePassword="service" />
<cf:Document id="doctestnow" action="generate" format="pdf" result="handleResult(event)" fault="handleError(event)" />
CFaaS has two special security requirements. First, you must go to User Management and specifically create a user and then give them access to particular services. In this case I gave the user, service, access to the Document service. Secondly, you have to specify which IP addresses are allowed to use the service. Now - I have to say - this is a bit troubling. I get the idea behind it - but it's going to be a problem for an intranet. I can't imagine you would need to enter each and every single IP address of your corporation by hand. But - that seems to be the case for right now. Hopefully that will change before release.
The code handling rendering is about as simple as it gets:
private function renderSourceAsPDF():void {
var source:String = sourceText.text;
if(source.length == 0) return
doctestnow.content = source;
doctestnow.execute();
}
Essentially - if I ttyped something, execute the CF service. My services result handler then simply uses the HTML component to render the PDF.
private function handleResult(event:ResultEvent):void {
res=event.result.toString();
pdfviewer.location=res;
}
Note that I had gotten a URL back, like Terry's demo, but I went ahead and loaded the result in the component.
I was going to package up the demo, but it's usability by the public is very limited. I'd recommend simply copying my code into a new Flex Builder project. Remember to include the cfservices.swc file with your project!
Archived Comments
Dead Bike - Live Cycle. Beer is mine.
You, sir, get one file Michelob Ultra.
Don't I already owe you 24? Just subtract one...
As just an update, I spoke with Hermant @ Adobe, and he said you CAN supply an IP range, ie: 10.*.20-30.30-50. The admin isn't clear on this so I'll probably file an ER to make it more obvious.
That is pretty freakin sweet! Would this work with cfmap? As a more general question, would this work on all tags?
I think I'm missing something here - what is this for? I've never dug much into Flex or livecycle, what does this offer me if I'm building standard html-based coldfusion code?
It is an example of using a ColdFusion feature in an AIR app. AIR doesn't have the ability to turn HTML into PDF. CF does. But I can use the CF power in my AIR app with this new CF9 feature.
@Will: No, it only works with certain services. I don't remember them all off the top of my head - check the docs. I think they are: cfdocument, cfpdf, cfimage, cfmail, cfpop.
Gotcha, so it's a remote interface into CF to use CF to 'do stuff' for RIAs.
(lot's of 'to's there, apologies, but that's the way it came out!)
@Paul: Yep, and not just for Flex, you can use them via web services as well, which means PHP/Java/.Net apps could use the services as well.
This entry is being published (albeit, poorly -- no code samples, etc) here: http://www.mynightclockonli...
Just thought you might like to know.
Thanks.