A few weeks ago I blogged an example of a "complete" cffileupload demo. Most examples of this tag are very simplistic and don't reflect what a typical form would consist of - ie both a multi-file uploader along with other form fields. A reader commented that they were curious if this could be combined with some sort of preview. I had recently done a blog entry on a related JavaScript library but today I've modified the CFFILEUPLOAD one to add a preview. As this uses most of the code from the original example, I strongly urge you to read that one first. I'll just be explaining the differences and none of the existing code.
To begin, I modified my cffileupload tag to run JavaScript on every file upload. That was as simple as adding the oncomplete argument:
<cffileupload extensionfilter="jpg,jpeg,gif,png,bmp,tiff,pdf" name="portfoliofiles"
maxfileselect="5" title="Portfolio Images" url="fileupload.cfm?#urlEncodedFormat(session.urltoken)#"
oncomplete="previewfile">
(By the way, I also added PDF to the list of extensions, more on the later.) The previewfile function will be passed an object containing the filename and the result from our server side code that handles uploads. Our demo code uses the same name as the user's file, so there is no need to worry about the file having a different name on the server. Here is what I did with the result:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
function previewfile(file) {
var previewHTML = '<span class="previewSpan"><img src="preview.cfm?s=' + file.FILENAME + '"></span>'
$("##previewArea").append(previewHTML)
}
</script>
Pretty complex, eh? All I needed to do was create some simple HTML. I point to a new CFM called preview and pass in the file name. Let's take a look at preview.cfm.
<cfparam name="url.s" default="">
<cfif isImageFile(session.myuploadroot & "/" & url.s)>
<cfimage action="read" source="#session.myuploadroot#/#url.s#" name="img">
<cfset ext = listLast(url.s,".")>
<cfset imageScaleToFit(img,125,125)>
<cfelse>
<cfimage action="read" source="default.jpg" name="img">
<cfset ext = "gif">
</cfif>
<cfset bits = imagegetblob(img)>
<cfcontent type="image/#ext#" variable="#bits#">
So what's going on here? Remember that we use a special folder in the virtual file system for the user's uploads. Because of this we can source a CFIMAGE to the file requested. We can also check to see if the file is a valid image. If it isn't, we can use a default picture instead. The final thing we do is get the actual bits and serve it up via cfcontent. Here is a screen shot of the result. Notice that I could have made this look far nicer.
Hopefully this makes sense and is useful!