• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 789
  • Last Modified:

Running a ColdFusion page in the background

I'm having a surprising amount of trouble finding out how I can have a user action fire off a background coldfusion process. I know this can be done with cfschedule, but i need to pass specific parameters to the template before proceeding.

I'm looking for a way to pass parameters to a CFM and run it, but not hang the user up in the process.  Basically, I want to initiate a rather large FTP upload with what the user has entered into the html form.  

Is there a way to allow the user to write the file to the server and locate away, while in the process, firing off a template that will run a rather long process for moving the file to where it needs to be?
0
joezizzo
Asked:
joezizzo
  • 3
  • 3
1 Solution
 
kyle1830Commented:
when the form submits, open a small window that says "Processing file" running the upload process.  when the small window loads have an onload event that send the focus back to the opener window.  You can even send the opener to another page.

small window:
<body onload="opener.focus();opener.location.href='/index.cfm';">

Kyle
0
 
kyle1830Commented:
here is what you would do on the form to get it to send the fields to the popup
<form action="processpage.cfm" method="post" target="mywin" onsubmit="window.open('','mywin','resizable,height=200,width=200,scrollBars=yes');">
    <input type="Text" name="test" value="Test">
    <input type="Submit" name="submit" value="submit">
</form>


then when the process window finishes the upload code add a window close function.

<script>
alert("Finished processing");
window.close;
</script>
0
 
mrichmonCommented:
If it is just a page that you want running then yes.

One method to do this is to have the page work in the background.

You can do this using an iframe (or a better XML method if you exclude certain older browsers like IE 5 for Mac)

THe way to do this is to have the button call a function in your page that looks like this:

<script type="text/javascript" language="JavaScript">
function CallPage()
{      
     callToServer("MyProcessPage.cfm?Var1=" + #var1# + "&var2=" + #var2#);
}
</script>

Or have javascript get the values instead of being coded in  like so:

function CallPage()
{      
     callToServer("MyProcessPage.cfm?Var1=" + document.getElementById("var1").value + "&var2=" +  document.getElementById("var2").value);
}


Then if you want to display a message to the user whenthe process is done add a function like the following


function Complete()
{    
     document.GetElementById("completemessage").innerHtml = "Process Complete";
}

The MyProcessPage.cfm would be a cold fusion page with your code to run the process on it - and it would accept all parameters via URL.

It would look like:

<cfquery datasource="myDSN" name="myquery">
whatever here
</cfquery>

<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<cfoutput>
<body onLoad="window.parent.Complete();">
</body>
</cfoutput>
</html>


SO then the onyly thing you need is to include the following javascript file to make the callToServer function work:

save as iFrameRPC.js

// ****************BEGIN FILE******************************************
var IFrameObj; // our IFrame object

function callToServer(backgroundURL) {
     if (!document.createElement)
     {// todo :: implement some kind of redirection if browser doesn't support creating of dom object
          return true;
     }
       
     var IFrameDoc;
     var URL =  backgroundURL;
     if (!IFrameObj && document.createElement)
     {// create the IFrame and assign a reference to the object to our global variable IFrameObj.
          // this will only happen the first time callToServer() is called
          try
          {
               var tempIFrame=document.createElement('iframe');
               tempIFrame.setAttribute('id','RSIFrame');
               tempIFrame.style.border='0px';
               tempIFrame.style.width='0px';
               tempIFrame.style.height='0px';
               IFrameObj = document.body.appendChild(tempIFrame);
               
               if (document.frames)
               {// this is for IE5 Mac, because it will only allow access to the document object
               // of the IFrame if we access it through the document.frames array
                    IFrameObj = document.frames['RSIFrame'];
               }
          }
          catch(exception)
          {// This is for IE5 PC, which doesn't allow dynamic creation/manipulation of iframe object.
               // Instead, we'll fake it up by creating our own objects.
               iframeHTML='\<iframe id="RSIFrame" style="';
               iframeHTML+='border:0px;';
               iframeHTML+='width:0px;';
               iframeHTML+='height:0px;';
               iframeHTML+='"><\/iframe>';
               document.body.innerHTML+=iframeHTML;
               IFrameObj = new Object();
               IFrameObj.document = new Object();
               IFrameObj.document.location = new Object();
               IFrameObj.document.location.iframe = document.getElementById('RSIFrame');
               IFrameObj.document.location.replace = function(location) {this.iframe.src = location;}
          }
     }          
 
     if (navigator.userAgent.indexOf('Gecko') !=-1 && !IFrameObj.contentDocument)
     {     // we have to give NS6 a fraction of a second
           // to recognize the new IFrame
           setTimeout('callToServer()',10);
           return false;
     }
 
     if (IFrameObj.contentDocument)
     {     // For NS6
          IFrameDoc = IFrameObj.contentDocument;
     }
     else if (IFrameObj.contentWindow)
     {     // For IE5.5 and IE6
          IFrameDoc = IFrameObj.contentWindow.document;
     }
     else if (IFrameObj.document)
     {     // For IE5
           IFrameDoc = IFrameObj.document;
     }
     else
     {
          return true;
     }
 
     IFrameDoc.location.replace(URL);
     return false;
}
//*****************END FILE***********************


(Watch out for some wrapping (due to forum) of above that should be on one line....)

ANd include in your project as <script type="text/javascript" language="JavaScript" src="iframeRPC.js"></script>
0
Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

 
mrichmonCommented:
I see kyle was positng while I was typing.

His method works too, but I am not sure what happens if they close the pop-up or have pop-up blockers on...

THe background method I decscribed doesn't use pop-ups so you don't have to worry about it being blocked, but the action is transparent to the user.....
0
 
kyle1830Commented:
mrichmon, good solution to "bypass" blockers.  I like it!.

My Intranet uses the "popup" method and since I control the blockers, my site is always allowed to "pop".   It's nice making the rules, but I lose out on having to think outside the box sometimes.

One ?..... since this is running in the background, what happens if the user clicks another link on the page before the process is finished?  I assume it would go to the new page and end processing.  How would you prevent this?

OK that was two questions?
0
 
mrichmonCommented:
No it actually is a separate page so the processing *should* complete, but you won't get the complete message.

I say *should* since I don't kow what will happen with Really Long processes.....
0
 
INSDivision6Commented:
Even both methods described above [may] work, a few comments:

If script execution is disabled in the browser, non of the above methods work.  Since massive pop-ups attacks, many people nowdays do not allow scripting.  So plain and simple target="_BLANK" may be a better choice.

There are pure server side solutions for this problem:

1. Use CFHTTP with a short timeout value that starts the background process with parameters needed. CFCACTH exception, ignore error.  No need to wait for results of CFHTTP (we don't care). Even HTTP connection is broken, the background processing will run and this is what we need.  Continue the main script, as needed.

2. If you under Windows, get this tag that supports this kind of processing:

http://www.cftagstore.com/tags/cfxhttp5.cfm
0

Featured Post

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now