Earlier this week I blogged about the new multi-file uploader in ColdFusion 9. While that control handles the front end support for handling multiple uploads, it works hand in hand with a new update to the cffile tag to support multiple file uploads. I did some digging into this and discovered some interesting tidbits.
First - the docs mention that when using cffile/action="uploadall", you get an array of CFFILE structures. This is true - but you will notice that if you use the multi-file uploader that the array will always contain one item. Why? The front end UI control may upload 2 or more files, but it's only going to upload one at a time. In fact, cffile/action="uploadAll" is kind of pointless with that control. It will always only have one upload at a time.
Second - you certainly can use cffile/action="uploadall" without using the new multi-file uploader. You can use it for hard coded forms like so:
<form action="test3.cfm" enctype="multipart/form-data" method="post">
<input type="file" name="file1" id="file1"><br/>
<input type="file" name="file2" id="file2"><br/>
<input type="file" name="file3" id="file3"><br/>
<input type="submit" name="submit">
</form>
In this case, cffile/action="upload" automatically finds all the file fields and processes them in order. Unfortunately you don't get information about the particular form field. The order seems to match the order of the form itself, but I'm not sure that is guaranteed. I'd probably say it is safe to assume it does.
Archived Comments
It stinks, but it makes sense since Flex will only let you post one file per request. I really wish they'd lift that limitation.
Just to note the downside to the <cffileupload tag like all uses of flash for File Uploading so far it doesn't handle authenticated domains, so for use on intranet's or locked down sites via security it doesn't work as well.
Hey Michael - this is a stretch, but have you ever tried passing the session token to the page that performs the upload? It may trick the server into believing that the Flash request is a normal authenticated user request and allow it to happen. Just a thought - let me know if you're not sure how to do what I'm suggesting.
As of CF9.0 Final, result attribute cannot be in local scope, otherwise the result is a array with 1 null element.
http://cfbugs.adobe.com/cfb...
Did you use result="local.foo" or var foo="", result="foo"?
Either one, var first, or inline "local." , same result.
The files got uploaded, but when you dump the result to a file, it'll complain array element 1 is null.
I don't know how what magic scope cffile uploadall uses to keep track of multiple files over multiple requests like how cffileuploader uses.
When uploading multiple files with uploadall, can anyone provide a pointer on how to easily sort the file sizes into ascending order via the data provided in the cffile result array? Everything I have thought of so far, is rather long and drawn out, making me think, there has got to be a better way.
Note. I realise sorting can be done with cfdirectory, however, it does not provide file extension info, other than in the entire filename, and I need that too.
Update. I ended up extracting the file extension using the listLast function, e.g. listLast(directorySelect.name, ".")
Any better ideas?
Nope, seems fine to me. Of course, not every file has an extension. For example, many open source projects will have a README file. Your code should handle that.
A good point. Fortunately, listLast handles that fine :)
I also decided it was far too hard to work out what extensions to allow/disallow, so I used the Outlook 2013 blocked attachment list as a starting point:
http://office.microsoft.com...
I know this is an old post, but I am trying to do multiple file upload using the simple form and cffile/action=uploadall. My problem is how do I get the server file names for all the files I uploaded? With a single file, it' just cffile.serverfile How do I parse it to obtain the file names? Thanks.
Are you using 2+ input tags on the front end? If so, the results in cffile is an array if I remember right. The easiest thing to do is to just cfdump the cffile result and you will see for yourself.
Yes, I have tried 2 input tags. I just tried the cfdump right after cffile:
<cfdump var="#cffile#">
It only showed the values for the second file :(
Show me the entire template, via a Gist though.
https://gist.github.com/tap...
Hmmm. That looks right to me. It should be an array of cffile results, not just one struct. You're really sure you selected two different files - one for each input field?
This is upload file page with original 5 inputs but entered only 2 and the result of cfdump on the next page.
Everything looks right to me code wise. What version of CF? Are you 100% patched?
CF version 9,0,0,251028 Enterprise UNIX
Wow, that's old. All I can suggest is trying it on CF11 (or heck, even 2016) and if it works, then you've found a bug in CF9.
You can also do it manually - so if form.file1, process it. if form.file2, etc. That would work for you too and be minimal more coding.
You mean cffile/action=upload one by one instead of uploadall?
Yep. I think you have 5 file inputs? It would take roughly 5 minutes to recode your app. :)
Thanks Raymond. I have whole bunch of processes for each of the uploaded file e.g. check if image, extension, resize and add to database. I don't want to re-code it 5 times. How can I loop it so that I can have 1 set of process for all 5 different form fields?
Can I simply put a
<cfloop index="i" from="1" to="5">
check if the form field is blank, if not do the cffile with fileField="form.upfile#i#"?
I am getting an error on
<cfif len(form.upfile#i#)="" gt="" 0=""> apparently I am not doing it right.
I have add a productupload2.cfm in the GIST
https://gist.github.com/tap...
So yes, you can just loop, and yes, your cfif code is wrong. You would want something like this:
<cfif len(form["upfile#i#"])="">
This uses the Form as a structure, which it is. :)
While checking the length of the form file I noticed that it actually uploads it already. Instead of getting the actual file name e.g. myimage.jpg I am getting a long tmp file name. Is that correct?
Well yes, cffile technically just handles the processing of the file after its up. By seeing if the temp value exists, you know something was chosen.