Discussion:
Downloading files to user
(too old to reply)
wrkoch
2006-05-13 02:11:00 UTC
Permalink
Hello!

I am using Flex front end in conjunction with CF backend to create a file,
then download it to the user. The series of events is:

Flex calls the first CF page using LoadVars:
my_lv.send("filemaker.cfm","new1","POST");"

The filemaker runs a query andcreates a file on the server, then calls a
download page, passing it the file name like so:
<SCRIPT language="JavaScript1.2" type="text/javascript">

window.open("sendfiletouser.cfm?outputfile=<CFOUTPUT>#URLEncodedFormat(OutputFil
e)#</cfoutput>","new1");
</SCRIPT>

The sendfiletouser.cfm basically uses a CFHEADER/CFCONTENT combo to squirt the
file to the user (obviously I set the variables properly)
<CFHEADER name="Content-Disposition" value="attachment;
filename=#FileName#">
<CFCONTENT type="#MimeType#" file="#OutputFile#" deletefile="yes">

It works GREAT! Files go out exactly how they need. Except?.

There is a window left behind. Yuck. I could use frames, creating a zero
height frame to "hold" the new1 window name but I really don't want to do that.
I can't write out code following the cfcontent so.....

Does anyone know how I can fix this? Or another way of sending a file out to
the user from CF without leaving a window behind?

Cheers!
drforbin1970
2006-05-15 14:27:21 UTC
Permalink
You should not need the popup window. Just call the sendfiletouser.cfm file
directly from the first page. The CFHEADER/CFCONTENT will spawn the download
prompt window. Try this as an example:

<form method="post" action="##">
<input type="text" name="enc_key" value="123">
<input type="submit">
</form>

<cfif IsDefined("Form.enc_key")>
<cfheader name="Content-Disposition" value='attachment; filename="key.key"'>
<cfcontent type="unknown"><cfoutput>#Form.enc_key#</cfoutput>
</cfif>
wrkoch
2006-05-15 14:45:16 UTC
Permalink
It's not the filemaker.cfm that is causing the problem. It is the loadvars.
The send method creates a window called "new1". The window.open in filemaker
writes to this window. The CFCONTENT (wherever it is) prevents me from
writing out code to close the "new1" window.

Trick would be to download the file automatically without using
CFHEADER/CFCONTENT so control of the window could be retained. I was thinking
maybe some JavaScript or even a Java process (I am not Java literate but I bet
there would be a way)
DJ Jamba
2006-05-15 22:05:39 UTC
Permalink
Try this:

<SCRIPT language="JavaScript1.2" type="text/javascript">
var fileWin =
window.open("sendfiletouser.cfm?outputfile=<CFOUTPUT>#URLEncodedFormat(OutputFil
e)#</cfoutput>","new1");
setTimeout("fileWin.close()",3000);
</SCRIPT>
wrkoch
2006-05-16 03:00:51 UTC
Permalink
Good part is it does close the window. Bad part is it pops up a message asking
wheter or not the user wants to close the window. If they pick yes, then no
download. If no, the window is still left behind. I added more time to the
timeout which helped.

I think you are are on the right track. What would be really good is if the
close method could be fired when the download is complete. I don't know if
that event is available......
drforbin1970
2006-05-16 14:19:09 UTC
Permalink
Are you serving an actual file on the server to the user or using CFCONTENT to serve dynamically built data?
DJ Jamba
2006-05-22 07:29:15 UTC
Permalink
Hi
Try this:
In 'filemaker.cfm' place a hidden form:

<form name = "aForm" action="sendfiletouser.cfm" method="post"
onsubmit="return getFiles(this);">
<input type="Hidden" name="theFile"
value="<CFOUTPUT>#URLEncodedFormat(OutputFile)#</cfoutput>">
(....other hidden fields for validation etc...)
</form>

...at the top of this page, your JS function can do some basic client
validation but to simplify:

<SCRIPT language="JavaScript1.2" type="text/javascript">
function getFiles(theForm) {
if (theForm.theFile != "") {
theForm.submit();
}
}
</SCRIPT>

...then in 'sendfiletouser.cfm' ...
<CFIF isDefined("FORM.theFile") AND Len(Trim(FORM.theFile)) GT 1>
<CFHEADER name="Content-Disposition" value="attachment;
filename=#Trim(FORM.theFile)#">
<CFCONTENT type="#MimeType#" file="#Trim(FORM.theFile)#" deletefile="yes">
</CFIF>

This method does not involve a popup window at all - and because the action
page returns CFCONTENT, the posting page remains where it is...
(Works in IE5+, NS6+, Firefox 1.0.4+, Mozilla 1.7.5+)

:o)

Jam
wrkoch
2006-05-22 11:07:07 UTC
Permalink
I have already went down this path. That is the reason why there is a
sendfiletouser.cfm in the first place -- to allow me to use CFCONTENT.

The problem is that I WANT to close the posting page (filemaker.cfm) window.
The popup window is being created by the FLEX application. I have no choice
but to create the popup that way since I don't want my FLEX app over-written.
Flex uses loadvars to fire filemake.cfm into the popup. Filemaker.cfm runs and
in turn downloads the file to the user using sendfiletouser.cfm. I am left
with an empty window that I can't seem to close.

I need an event in sendfiletouser.cfm that is triggered when the user download
via CFCONTENT is complete.
drforbin1970
2006-05-22 14:02:17 UTC
Permalink
Think I figured it out, try this:

<SCRIPT language="JavaScript1.2" type="text/javascript">
//create variable containing new2 window open, attributes make window
'disappear'
var new2 =
window.open('sendfiletouser.cfm?outputfile=<CFOUTPUT>#URLEncodedFormat(OutputFil
e)#</cfoutput>','n_new2','width=1,height=1,screenx=-2000,screeny=-2000,left=-200
0,top=2000,z-lock=0,status=0,titlebar=0,location=0,toolbar=0,menubar=0,scrollBar
s=0,alwaysLowered=false,resizeable=0');

function close_em(){
//while new1 open, keep trying to close new2
while(window.opener != null && !window.opener.closed){
new2.close();
if(new2.closed){ //if new2 is closed, close new1
window.opener=null;
window.close();
}
}
}
//wait two seconds before checking window state, give sendfiletouser.cfm time
to process, increase if necessary
setTimeout("close_em()",2000);
</SCRIPT>

This SHOULD work, let me know.
wrkoch
2006-05-22 14:47:12 UTC
Permalink
This was already proposed by DJ Jamba and tested by me. Check the thread for 5/15/06.
DJ Jamba
2006-05-23 12:05:25 UTC
Permalink
Not sure if you are going to find an easy resolution to this without changing
the FLEX logic :( - however, seeing as my first post was 'on the right track',
how about this:

USUALLY when JS executes a window.close(), you should only get the warning if
you have toolbars etc. If your FLEX app creates a popup without
toolbars,scrollbars, statusbar etc - you should not get the window closing
warning.

Is it not possible for you to create a popup function in your FLEX app and
pass the URL to this, then take the script from my first post and try that?
wrkoch
2006-05-23 13:01:51 UTC
Permalink
Ahhh -- that would explain all the nag screens! I just learned something!

I am using a LoadVars.send in the FLEX application. I have no control over
the window with LoadVars. I will look at changing it over to a
getURL("javascript:open(code here)) format in order to get control of the popup
window. Let me dig into this and post my results.
drforbin1970
2006-05-16 16:13:38 UTC
Permalink
Try adding the last two window lines and see if it works:

<SCRIPT language="JavaScript1.2" type="text/javascript">

window.open("sendfiletouser.cfm?outputfile=<CFOUTPUT>#URLEncodedFormat(OutputFil
e)#</cfoutput>","new1");
window.opener=null;
window.close();"
</SCRIPT>
wrkoch
2006-05-16 18:06:43 UTC
Permalink
Nope, that shut the window the instant it loaded, giving no time for the user
to download the file.

The filemaker.cfm creates a file on the server. The sendfiletouser.cfm uses
CFHEADER/CFCONTENT to download it to the user.

I guess what I'm looking for is a window event that I can trap when the
download is complete or the user cancels. Or a JAVA way of doing this so I can
avoid CFCONTENT.
drforbin1970
2006-05-16 23:12:04 UTC
Permalink
Beauty of CFCONTENT is that you can delete the file after you serve it, I
understand. I think I may have the answer.

Add the 'openercheck' line to your JavaScript in your filemaker.cfm file.

<SCRIPT language="JavaScript1.2" type="text/javascript">

window.open("sendfiletouser.cfm?outputfile=<CFOUTPUT>#URLEncodedFormat(OutputFil
e)#</cfoutput>","new1");
openercheck =
window.open("open_check.cfm?called=y","closeall","width=0,height=0,x=-2000,y=-20
00");
</SCRIPT>

Create a file in the same directory called open_check.cfm consisting of:

<cfif IsDefined("URL.called")>
<SCRIPT language="JavaScript1.2" type="text/javascript">
while(window.opener != null && !window.opener.closed){
opener.close();
window.close();
}
</script>
</cfif>

How this should work is 'openercheck' will be a window that will monitor
'new1' since 'new1' is it's opener. I sized 'openercheck' window small and
placed it off the viewable browser space so user will not see it. The
'openercheck' window will continually monitor the state of it's opener (new1)
and keep trying to close it (it will be unable to close it while the file
download prompt is displayed to the user; when the user clicks Save, the
'openercheck' window will have the opportunity to close it's opener (new1) and
itself. But the file save screen will still be active so the user can finish
downloading the file.

You will notice the open_check.cfm?called=y line, this is to let
open_check.cfm know it WAS called. So if someone runs open_check.cfm via
mysite.com/open_check.cfm it will not execute the JavaScript; since the
script is a continuous loop.

Since 'new1' is a spawned window via your .send command, we should be able
to close it. Hopefully, this will work. Let me know either way if you can.
I've only tested in IE6.
wrkoch
2006-05-17 12:58:37 UTC
Permalink
I tried it and it wasn't workable because IE keeps throwing up a window saying:

The web page you are viewing is trying to close the window
Do you want to close the window?

It does this while the file open/save window is up. If they save and then say
yes to the nag screen, both windows close. But if they save yes before they
download, both windows close and no download. This will confuse the users to
no end.

I thnk the only reasonable way to close the window is to trap the download
event directly but I don't know if this exists in the DOM. Or do a JAVA thing.
drforbin1970
2006-05-17 13:50:15 UTC
Permalink
Try this, in your open_check.cfm file, put window.opener=null; before the
opener.close(); line. If that doesn't work, add the window.opener=top; line.

window.opener=null;
opener.close();
window.close();

window.opener = top;
window.opener=null;
opener.close();
window.close();

See if that works.
wrkoch
2006-05-17 15:50:37 UTC
Permalink
Nag screen went away but the windows (two of them) don't close.
drforbin1970
2006-05-17 16:55:06 UTC
Permalink
Just to be clear, use either/or of these, don't use all seven lines:

window.opener=null;
opener.close();
window.close();

-or-

window.opener = top;
window.opener=null;
opener.close();
window.close();
wrkoch
2006-05-17 20:43:56 UTC
Permalink
Right.

I tried

<cfif IsDefined("URL.called")>
<SCRIPT language="JavaScript1.2" type="text/javascript">
while(window.opener != null && !window.opener.closed){
window.opener=null;
opener.close();
window.close();
}
</script>
</cfif>

AND

<cfif IsDefined("URL.called")>
<SCRIPT language="JavaScript1.2" type="text/javascript">
while(window.opener != null && !window.opener.closed){
window.opener = top;
window.opener=null;
opener.close();
window.close();
}
</script>
</cfif>
drforbin1970
2006-05-18 13:28:44 UTC
Permalink
The problem seems to be the way 'new1' is opened. Try this, in filemaker.cfm,
just put this:

<script>
window.opener=null;
window.close();
</script>

If that closes 'new1' right after it opens without a prompt, then we can go
from there.
wrkoch
2006-05-18 21:10:44 UTC
Permalink
It closed just fine.
DJ Jamba
2006-05-23 13:33:11 UTC
Permalink
if it's anything like FLASH/actionscript:

(better to dynamically create the paramters but quick example)

getURL("javascript:window.open('filemaker.cfm','new1','height=400,width=400
,toolbar=no,scrollbars=no,statusbar=no,directories=no');");
DJ Jamba
2006-05-23 14:53:08 UTC
Permalink
really should use a form with hidden fields then
:)
(the filemaker.cfm could submit hidden fields - but this may be too much of a change in your logic)
wrkoch
2006-05-23 17:32:38 UTC
Permalink
I have been doing battle with this and made some progress. I surrendered on
the post and decided to take things one step at a time. I just passed the
variables as part of the url. I did get Flex to open a window without
toolbars, etc.

I tried the setTimeout("fileWin.close()",3000); Nag screens have disappeared.
Works great only if the user picks something before the time expires. If not,
it leaves the window hanging.

I tried the open_check.cfm monitor method. That did pretty good except on a
multitabbed browser. I think what is going on there is that it is eating the
processor. I tried to move the opener.close and window.close into a function
which was called by a timer but i just couldn't make it work.
DJ Jamba
2006-06-21 23:32:13 UTC
Permalink
any news?
wrkoch
2006-06-22 00:08:51 UTC
Permalink
No and yes. I was unable to find any way to close the window. I tried more
techniques than you can imagine. Even rewrote the download to use JAVA. No
luck. But...

I did solve the problem. I noticed that the Flex generated html code was
using a zero height IFRAME to hold the history data. I just added another
named IFRAME and pointed the loadvars.send at it. Works great!

Loading...