27 Replies Latest reply on Jun 21, 2006 5:08 PM by wrkoch

    Downloading files to  user

    wrkoch Level 1
      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 and creates 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(OutputFile)#</cfou tput>","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 don't want to over-write the Flex ap running so I need a new window. 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!

        • 1. Re: Downloading files to  user
          drforbin1970 Level 1
          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>
          • 2. Re: Downloading files to  user
            wrkoch Level 1
            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)
            • 3. Downloading files to  user
              DJ_Jamba
              Try this:

              <SCRIPT language="JavaScript1.2" type="text/javascript">
              var fileWin = window.open("sendfiletouser.cfm?outputfile=<CFOUTPUT>#URLEncodedFormat(OutputFile)#</cfou tput>","new1",'toolbars=no,resizeable=no,width=10,height=10,left=-20,top=-20');
              setTimeout("fileWin.close()",3000);
              </SCRIPT>

              I added some more params to your popup in case you wanted to hide it

              jam
              • 4. Re: Downloading files to  user
                wrkoch Level 1
                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......
                • 5. Re: Downloading files to  user
                  drforbin1970 Level 1
                  Are you serving an actual file on the server to the user or using CFCONTENT to serve dynamically built data?
                  • 6. Re: Downloading files to  user
                    drforbin1970 Level 1
                    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(OutputFile)#</cfout put>","new1");
                    window.opener=null;
                    window.close();"
                    </SCRIPT>
                    • 7. Re: Downloading files to  user
                      wrkoch Level 1
                      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.
                      • 8. Re: Downloading files to  user
                        drforbin1970 Level 1
                        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(OutputFile)#</cfout put>","new1");
                        openercheck = window.open("open_check.cfm?called=y","closeall","width=0,height=0,x=-2000,y=-2000");
                        </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.
                        • 9. Re: Downloading files to  user
                          wrkoch Level 1
                          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.
                          • 10. Re: Downloading files to  user
                            drforbin1970 Level 1
                            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.

                            • 11. Re: Downloading files to  user
                              wrkoch Level 1
                              Nag screen went away but the windows (two of them) don't close.
                              • 12. Re: Downloading files to  user
                                drforbin1970 Level 1
                                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();
                                • 13. Re: Downloading files to  user
                                  wrkoch Level 1
                                  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>
                                  • 14. Re: Downloading files to  user
                                    drforbin1970 Level 1
                                    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.


                                    • 15. Re: Downloading files to  user
                                      wrkoch Level 1
                                      It closed just fine.
                                      • 16. Re: Downloading files to  user
                                        DJ_Jamba Level 1
                                        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+)

                                        )

                                        Jam
                                        • 17. Re: Downloading files to  user
                                          wrkoch Level 1
                                          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.
                                          • 18. Downloading files to  user
                                            drforbin1970 Level 1
                                            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(OutputFile)#</cfou tput>','n_new2','width=1,height=1,screenx=-2000,screeny=-2000,left=-2000,
                                            top=2000,z-lock=0,status=0,titlebar=0,location=0,toolbar=0,menubar=0,
                                            scrollBars=0,alwaysLowered=false,resizeable=0');

                                            function close_em(){ //this function gets called by setTimeout
                                            //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.
                                            • 19. Re: Downloading files to  user
                                              wrkoch Level 1
                                              This was already proposed by DJ Jamba and tested by me. Check the thread for 5/15/06.
                                              • 20. Re: Downloading files to  user
                                                DJ_Jamba Level 1
                                                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?
                                                • 21. Re: Downloading files to  user
                                                  wrkoch Level 1
                                                  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 pen(code here)) format in order to get control of the popup window. Let me dig into this and post my results.
                                                  • 22. Re: Downloading files to  user
                                                    DJ_Jamba Level 1
                                                    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');");
                                                    • 23. Re: Downloading files to  user
                                                      wrkoch Level 1
                                                      Yup -- just have to figure out the the proper syntax to get the variables to transfer under a POST. I want to keep them hidden.
                                                      • 24. Re: Downloading files to  user
                                                        DJ_Jamba Level 1
                                                        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)


                                                        • 25. Downloading files to  user
                                                          wrkoch Level 1
                                                          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 changed this to setInterval and that took care of that since the download stops close. I think it may have created another issue in multi-tabbed browser -- it closes the window before the download starts. I need to do more plaing around.

                                                          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'm going to try to move the opener.close and window.close into a function which is called by a timer and see if that helps.
                                                          • 26. Re: Downloading files to  user
                                                            DJ_Jamba Level 1
                                                            any news?
                                                            • 27. Re: Downloading files to  user
                                                              wrkoch Level 1
                                                              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!