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

Hi Monks,
I looking to add a feature on my program where a timer, like a progress bar will show on the browser screen while the program is waiting response from a DB query. My question is how could I do that, or how could I wait until some variable gets a values from the processed results from the DB and as soon as it gets a value the progress bar would be gone. Any help on that?
Thank you very much!

Replies are listed 'Best First'.
Re: Timer - Progress Bar
by edan (Curate) on Dec 13, 2004 at 13:54 UTC

        Yes, you're right. I just did a search for long CGI and found that other one (in a reply by you), so I assumed it was the one I thought it was, without really looking.

        --
        edan

Re: Timer - Progress Bar
by davorg (Chancellor) on Dec 13, 2004 at 13:47 UTC

    You really need to read the Perl Advent Calendar - Term::ProgressBar.

    Update: Ah. But, of course, that's for console-based applications and you're looking for a browser-based solution.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: Timer - Progress Bar
by Joost (Canon) on Dec 13, 2004 at 14:09 UTC
    "Real" progress bars are quite tricky, and I tend to avoid them. One trick I've used for this is as follows (untested code):

    #!/usr/bin/perl -wT use strict; use CGI; $|=1; # turn of output buffering.. # do some setup stuff, and print HTML headers here # display a simple (looped & animated) "loading" image print <<ENDHTML; <img src="loading.gif" name="loading"> ENDHTML # load stuff from the database... print <<ENDHTML; <script language="JavaScript"> <!-- document.images['loading'].src = 'empty.gif'; //--> </script> ENDHTML # print output
    You could also use CSS to put something else over the message after your done, which should eliminate the need for javascript. Adapt as you like.

      Since JS tends to be problematic -- my current client requires it be turned off, for example -- here's an idea of how to acccomplish this with CSS.

      /* Stylesheet Snippet */ .pbcont { background-color: #000; height: 20px; width: 250px; border: 1px solid #00c; margin: 0; padding: 0; } .pbarchunk { margin: 0; margin-right: 2px; padding: 0; background-color: #00c; width: 23px; height: 20px; }

      #!/usr/bin/perl use CGI; # Do CGI stuff # Print a lot of the HTML; print "<div class='pbcont'>"; while ($new_val < 100) { $new_val = &update(); # get the updated progress next unless $new_val > $old_val; print "<div class='pbar'> </div>"; } print "</div>\n";

      This is untested, but the basic idea is that writing the DIVs will cause colored blocks to appear inside a bordered bar. One could also get a lot more complicated, dealing with fractional percentages, absolute CSS positioning to make the progress bar go away, and other neat little tricks.

      Of course, if all you're interested in is letting the user know "something is happenning", you can use the parent post's idea with an animated GIF. This is basically what sites like PriceLine and the like use.

      radiantmatrix
      require General::Disclaimer;
      s//2fde04abe76c036c9074586c1/; while(m/(.)/g){print substr(' ,JPacehklnorstu',hex($1),1)}

      A related technique is to have the initial request not actually do any work but just return a page with the animated "loading..." image and a refresh header/metatag that causes the browser to issue another request for the "real" page; that second page can take as long as needed to generate the results which will then replace the first page.
      Actually the trick here worked with out a problem, and with out any complexity, just needed a little work.
      Thank you!
        I would love to see your final version. I am looking for a simple (and actual) upload progress bar for a working group that exchanges large jpg's and cad files.
      A nice sharing.
Re: Timer - Progress Bar
by saintmike (Vicar) on Dec 13, 2004 at 19:08 UTC
    Somewhat off-topic here, because the question is about web based solutions, but if you ever need to implement a progress bar on the command line, use Smart::Comments:
    use Smart::Comments; for my $j (1..500) { ### Compiling===[%] done select undef, undef, undef, 0.01; }
    Note that the entire progress bar code is hidden in the special ### comment.