Adobe Solution Partner

April 27, 2008

Shan’s Simple Examples: File uploads with Flex and ColdFusion

Filed under: ColdFusion, Flex & Flash, Shan's Simple Examples — Tags: , , — Shannon Hicks @ 2:18 pm

Someone in #flex was talking about how there were no good examples for doing uploads with Flex and ColdFusion. Sounded like an excellent topic to cover here. Now this example is a tiny bit more complex than previous examples, because I needed to cover two methods of functionality: single file uploads and multi-file uploads. Both processes are very similar, and in my code they actually share a method.

Here’s the MXML application:

<![CDATA[
import mx.controls.Alert;
private var myFileList:FileReferenceList;
private var myFile:FileReference;
private var uploadTarget:URLRequest = new URLRequest("upload.cfm");

private function init():void {
myFileList = new FileReferenceList();
myFileList.addEventListener(Event.SELECT,fileListSelected);

myFile = new FileReference();
myFile.addEventListener(Event.SELECT,fileSelected);
}

private function fileListBrowse():void {
// we only want to allow images to be uploaded
var imagesFilter:FileFilter = new FileFilter("Images", "*.jpg;*.jpeg");
myFileList.browse([imagesFilter]);
}

private function fileBrowse():void {
// we only want to allow images to be uploaded
var imagesFilter:FileFilter = new FileFilter("Images", "*.jpg;*.jpeg");
myFile.browse([imagesFilter]);
}

private function fileListSelected(e:Event):void {
// here we could do whatever we want, but we're just going to
// upload right away
uploadFromList();
}

private function fileSelected(e:Event):void {
// here we could do whatever we want, but we're just going to
// upload right away
uploadFile(myFile);
}

private function uploadFromList():void {
if (myFileList.fileList.length > 0) {
// if there are still files left to upload, continue
myFile = myFileList.fileList[0] as FileReference;
uploadFile(myFile);
} else {
// if there are no more files, stop
return;
}
}

// NOTE: this method is used for one or multiple files
private function uploadFile(f:FileReference):void {
// here we build out the other form items
var urlVars:URLVariables = new URLVariables();
urlVars.myFirstValue = 1;
urlVars.myOtherValue = "something else";

// add the form items to the request
uploadTarget.data = urlVars;
// set request the method to POST
uploadTarget.method = URLRequestMethod.POST;

// add the event listeners
// DataEvent.UPLOAD_COMPLETE_DATA only fires if data is returned and the flash player supports it
// otherwise, use Event.COMPLETE
f.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onDataComplete);
f.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
f.addEventListener(ProgressEvent.PROGRESS, progressHandler);

// show the progress bar
myProgress.visible = true;

// start the upload
f.upload(uploadTarget,"myUploadFieldName");
}

private function ioErrorHandler(e:IOError):void {
// there was some error, you'll want to tell someone
Alert.show("Error occured, oops!","I/O Error");
}

private function progressHandler(e:ProgressEvent):void {
// update the ProgressBar
myProgress.setProgress(e.bytesLoaded,e.bytesTotal);
}

private function onDataComplete(e:DataEvent):void {
// here we could handle whatever was returned by the server. XML is probably your best bet.
// var myResult:XML = XML(e.data); // would work for XML
var myResult:String = e.data;

// if there were multiple files, delete the one we uploaded and try another
if (myFileList.fileList.length > 1) {
// remove what we just uploaded
myFileList.fileList.splice(0,1);
// go upload another another
uploadFromList();
} else {
// if this was the last of a multiple file upload, remove it
if (myFileList.fileList.length > 0) {
myFileList.fileList.splice(0,1);
}

// we're done uploading
myProgress.visible = false;
return;
}
}
]]>

The comments point out all the nuances you need to know about. It does the major features, including passing more data with the file, what you can do with the progress event, how to do an upload queue, rather than uploading all selected files at the same time, and how to handle responses from the upload script. This code will work with any backend processor, not just ColdFusion.

Here’s the ColdFusion file:

<!--- this will upload the file --->
<!--- note that all formfields including FORM.myFirstValue and FORM.myOtherValue --->

myVal1 = FORM.myFirstValue;
myVal2 = FORM.myOtherValue;
<!--- here you can send stuff back to flex, only if the flash player is 9.0.28.0 or later --->

It doesn’t do much, but you can see how to get non-file data passed from flex, and how to send a response. Make sure that, when sending a response, you don’t send any whitespace before what you intend to send back to Flex. Also, note that your users need the Flash Player version 9.0.28.0 or later in order to send responses back to flex.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • LinkedIn
  • StumbleUpon
  • Technorati
  • TwitThis

5 Comments »

  1. I’m trying to pass in the value for uploadDestination, so it is not hard coded, and since I’m a newbie, I’m having difficulty with it. Could you help?

    I changed the following line in FlexFileUpload_cb.as from

    public var uploadDestination:String = http://www.xyz.com/Upload.cfm";

    to:

    public var uploadDestination:String = Application.application.parameters.uploadUrl;

    Then, in the index.cfm file that I have the flash file on, my flashvars code is as follows:

    "flashvars",’uploadUrl=<cfoutput>#urlEncodedFormat(uploadActionString)#</cfoutput>&historyUrl=history.htm%3F&lconid=’ + lc_id + ”,

    I can build the file fine, but when I go to run it, I get the following error and the flash movie does not show:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at FlexFileUpload$iinit()
    at _FlexFileUpload_mx_managers_SystemManager/create()
    at mx.managers::SystemManager/::initializeTopLevelWindow()
    at mx.managers::SystemManager/::docFrameHandler()

    Once again, thank you. If you can help me, I’d greatly appreciate it. Thanks.

    Comment by Go-Gulf — October 29, 2008 @ 12:00 am

  2. Did you add uploadUrl to both spots in your HTML code that embeds the flash? There’s two spots if I remember correctly.

    Comment by Shan — October 29, 2008 @ 12:00 am

  3. Hi! I was surfing and found your blog post… nice! I love your blog. :) Cheers! Sandra. R.

    Comment by sandrar — September 10, 2009 @ 4:51 pm

  4. Nice example.
    What about using CF cfc with cffile method?
    I’m trying to pass the name to my cfc method but at the time of upload I got an error missing enctype=”multipart/form-data”.
    Any ideas?
    Tks!

    Comment by Johnny — October 1, 2010 @ 12:40 pm

  5. Johnny-

    I’m pretty sure that it isn’t possible to post from flash to a CFC, that you have to post to a CFM.

    Comment by Shannon Hicks — October 1, 2010 @ 8:17 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

 

Server Down?

Maximize Web application uptime by drawing upon Webapper's years of experience tuning and stabilizing many of the world's largest ColdFusion Web applications. Contact us today!