francesca has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am writing some CGI programs. One program, say, step1.cgi, asks user to submit some information by an HTML form, and the second program, step2.cgi, processes the infomation and display the result. It will take quite some time to process the submitted request, so how can the webpage show something meaning to the user while waiting for the result? for example, show some text like "Processing in progress, please wait...".

Thank you.

--francesca

Replies are listed 'Best First'.
Re: Let users wait for the results
by rob_au (Abbot) on Feb 02, 2002 at 07:25 UTC
    In addition to the answer given by screamingeagle above, you may want to look at the column by merlyn which discusses a slightly more advanced variation of this technique.

     

    perl -e 's&&rob@cowsnet.com.au&&&split/[@.]/&&s&.com.&_&&&print'

      screamingeagle's response will only work if it is the building of the output that takes the time. Obviously, if it is a lengthy calculation followed by a quick display, nothing will be gained.
      The method in the column is interesting, but maybe a little clunky for the user. (Either having to repeatedly reload, or wait for the auto-reload to realize its done).
      If you want to get really fancy, you can try this:
      page1 contains a hidden IFRAME (in I.E.) or FRAME (in Netscape) called hidden. You can detect the broswer in a bit of javascript at the bottom of your page and do a document.write of the appropriate container.
      when the user submits the query, an onSubmit handler shunts the request to the hidden frame. I'm going to assume I.E. here, the code is similar for netscape:
      document.all.hidden.src="calculation.html?...";

      Then the handler exposes a hidden DIV (or ILAYER in netscape) containing the hold on message:
      document.all.message.style.visibility='visible';

      The handler returns false so that the page remains up. (You could also disable the submit button in here to prevent the user from repeatedly submitting the form while she's waiting).
      return false;

      The calculation script returns an empty page with an onload handler that redirects the top page to the results.
      onLoad="top.document.location.href='results.html?...'

      This assumes that the results are cached in a file or a session variable, or are simple enough to be passed through the request parameters.

      All this is probably too complicated and too much effort to be of value, but it is an option. I've had to use it in the past.
      Also, the flexibility of having a hidden communication channel in your web app comes in handy all over the place. The hidden frame can be used to silently update the server while the client is working. It can be used to log javascript errors in your server-side log files.

      -pete
      Entropy is not what is used to be.
Re: Let users wait for the results
by screamingeagle (Curate) on Feb 02, 2002 at 07:20 UTC
    you could disable buffering by using this at the top of the program :
    $| = 1;
    This will show the data as it is outputted by the program, rather than being buffered by Perl...
Re: Let users wait for the results
by Ryszard (Priest) on Feb 02, 2002 at 09:09 UTC
    Also, and slightly off topic, check out CGI::Application, and HTML::Template to add a nice structure to your application.. :-)

    Rather than have two cgi files, you can have just one, and scale it easily for your web app.

(cLive ;-) Re: Let users wait for the results
by cLive ;-) (Prior) on Feb 02, 2002 at 23:35 UTC
    You say "quite some time". If this really is quite some time, you might want to fork a process to do what needs doing and send a thank you page back to the browser that sets a cookie identifying the fork and quit.

    Get the forked script to store the cookie ID in a DB/log file somewhere. When the fork finishes, it removes this ID from the DB/log file. When the user clicks to see if the processing has finished, read the cookie and check it against the list of running process (fork) IDs in the DB/log file. If it's finished, proceed, otherwise send back a still processing message.

    Or something like that...

    cLive ;-)