Limiting individual file sizes in the Ajax based uploader in ColdFusion 9

This post is more than 2 years old.

ColdFusion 9 added a snazzy little Ajax-based (well, Flash based to be truthful) multi-file uploader. Just in case you haven't actually seen it, here is a quick snap shot of what it looks like:

I've done a few blog posts on this topic already. Today a reader sent in an interesting question. While the control provides a way to limit the total file size of uploads (using the maxuploadsize attribute), there is no direct way to limit the size of individual file uploads. This blog entry will show one way that can be accomplished. I'll be using jQuery for my solution but please note that this is not a requirement.

Ok, so the first problem we run into is that there is no support for noticing when a file is added to the queue. If there was, we could listen for that and simply throw an error then. The next problem is that there is no support for a "pre"-upload event. You get support for an upload complete event - but not one for right before the uploads begin. Luckily we have a way to work around this. We're going to disable the upload button and use our own logic to fire off the uploads. I'll show the entire template below and then walk you through what it does.

<html>

<head> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script> $(document).ready(function() { $("#uploadBtn").click(function() { //get all the files var files = ColdFusion.FileUpload.getSelectedFiles('myfiles'); if(files.length == 0) { alert("You didn't pick anything to upload!"); return; } var oneTooBig = false; for(var i=0; i<files.length; i++) { if(files[i].SIZE > 40000) { oneTooBig = true; alert("The file, "+files[i].FILENAME +" is too big. It must be removed."); } }

	if(!oneTooBig) ColdFusion.FileUpload.startUpload('myfiles');
});

}); </script> </head>

<body>

<cffileupload name="myfiles" maxuploadsize="10" hideuploadbutton="true"> <br><br> <input type="button" id="uploadBtn" value="Upload Mah Filez!">

</body> </html>

First - notice how in the cffileupload control I've used the hideuploadbutton attribute. As you can guess, this removes the button you would normally use to upload all the files. I've added my own button, uploadBtn, that will be used instead.

Now let's look at the JavaScript. When the upload button is clicked, I begin by using the ColdFusion Ajax API call, getSelectedFiles, to get an array of files in the control. Once I have that, it's rather trivial. I loop over each and if the file size is too big (I used 40K as an arbitrary limit), then I flag it and alert it to the user. If no file was too big I can then fire off the upload request, again using the document Ajax API call startUpload().

That's it. You can see here in this screen shot how the button was removed.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by SuperAlly posted on 8/14/2010 at 5:31 AM

This is great Ray. Thanks! I had wondered about and been asked about that myself.

Comment 2 by SuperAlly posted on 9/1/2010 at 8:06 AM

I finally got a chance to take a better look at this and when I try to "Upload Mah Filez!" nothing happens (using the code as shown).

I've only ever used cffileupload once and it was pretty much standard use via the docs, so it's entirely possible I missed the plot entirely!!

As I said, I didn't change anything, was just trying to get started with the example. Any thoughts on what I might have done wrong?

Comment 3 by Raymond Camden posted on 9/1/2010 at 8:09 AM

Right after

$("#uploadBtn").click(function() {

add

console.log("CLICK HANDLER RUN");

This will only work if you have Firebug, or Google Chrome (and ensure the JavaScript console is open).

Comment 4 by SuperAlly posted on 9/1/2010 at 8:23 AM

Works perfectly in Chrome and Firefox after adding that line!

Comment 5 by SuperAlly posted on 9/1/2010 at 9:20 AM

I apologize for the double post, I just wanted to correct myself a little and expand on that last statement...
The page works fine with or without the extra line in either Firefox or Chrome (although I did get a 'console' is undefined error in Firefox the first time I tried it before adding the line - Been fine since, even with it removed again) and does log the click under both when added.
The page does not work for me in Safari 5 (Mac).
Hope that clears up any confusion that I may have caused.

Comment 6 by Raymond Camden posted on 9/1/2010 at 3:54 PM

It does clear things up a bit - enough for me to test on my Mac.

Comment 7 by Raymond Camden posted on 9/1/2010 at 3:57 PM

I just tried it and it works fine. Let's try this. Keep the console message in and open up Safari's JS console. Also add a console.log("doc ready") after the document ready line. That should run on startup, and the other msg should run when you click. Please confirm that.

Comment 8 by SuperAlly posted on 9/1/2010 at 6:54 PM

Looks like there is an error:
TypeError: Result of expression '_650.getSelectedFileArray' [undefined] is not a function. ... cffileupload_swf.js:245
Didn't see this before, but it doesn't mean much to me unfortunately.

Comment 9 by Raymond Camden posted on 9/1/2010 at 6:59 PM

So if you do a console.log before and after ColdFusion.FileUpload.getSelectedFiles('myfiles')

you can see it breaks right there, right?

Comment 10 by SuperAlly posted on 9/1/2010 at 7:04 PM

That is correct, yes.

Comment 11 by Raymond Camden posted on 9/1/2010 at 7:06 PM

Hmm. Unfortunately that's Adobe shipped code, I can't help with that. It is odd that I don't get it with my Safari though. Is your code online where I can hit it?

Comment 12 by SuperAlly posted on 9/1/2010 at 7:20 PM

I don't have a copy anywhere online right now, no.
It's just a word for word copy of your demo right now though.

Comment 13 by Raymond Camden posted on 9/1/2010 at 7:22 PM

The reason I want to see is that maybe something on your server is wrong. If you use FIrebug, or Google net tools, or Safar's, but I'm not sure where - maybe you see a JS library not being loaded right.

Comment 14 by SuperAlly posted on 9/2/2010 at 1:10 AM

Sorry to pester you again with this, but I was able to get an example online, with the console commands added.
Doesn't work in Safari, Chrome or Firefox at this url.
http://www.cfdevshack.com/t...
Works locally as is. Debugging is not turned on.

Comment 15 by Daren Valentine posted on 9/2/2010 at 1:52 AM

I know this sounds crazy, but I can't get a basic cffileupload to display. Accessing the page from the server while inside the firewall and everything is beautiful. Using the same version of Firefox from outside the firewall, and the area where the control should be is blank. The source code view shows the exact same code.

any thoughts???

Comment 16 by Raymond Camden posted on 9/2/2010 at 1:59 AM

Something on your network is blocking /CFIDE files. Check there.

Comment 17 by Raymond Camden posted on 9/2/2010 at 2:01 AM

@Daren: Are you using 901? This API is 901 only I believe.

Comment 18 by SuperAlly posted on 9/2/2010 at 2:17 AM

901 would likely explain my issue. I will have to check the live version.
I know the standard cffileupload works in it's place but If this version only works under 901 though, that is probably the cause of my problem. Thanks again.

Comment 19 by Daren Valentine posted on 9/2/2010 at 3:02 AM

Will check the firewall to see what is going on! Works internal and in from the DMZ, just not from external. BTW tried to load the 9.0.1 update and it crashed my installation last week. Had to recover from an virtual server image.