Uploading files with progress indicator

Published:
Uploading files to the web server has become common part of almost any kind of web application. People use different technologies to solve this, but regardless of the technology used, it is always useful to have some kind of progress indicator shown to the visitor so he can see the upload progress. In this article I’m going to describe how to solve this using WhizBase - the simplest way known to me. Generally, in WhizBase uploading files is a really trivial task (very well covered in EE article by NurAzije you can find here) and showing a progress requires just a few additional steps. Note that unlike the basic upload example in NurAzije’s article, here we have to use WhizBase script even for creating upload form since we need WhizBase to generate form upload id for this particular upload. This article assumes that you know basic HTML and basic JavaScript, and I’ll try to explain WhizBase code (required for showing the progress) in as much detail as possible.

Because of the simplicity and cross browser compatibility I’ll use a pop-up window to show the upload progress, but the same principle can be used in combination with AJAX or IFRAME to display progress in same page or even to generate a graphic progress bar.

I’ll also use two WhizBase scripts shown below:

Script upload.wbsp:
<!--
                      [FormFields]
                      WB_AllowMultipart=T
                      WB_FULID=$wbif{"$wbv{image}"=""|t|f}
                      [Upload]
                      WB_Disallow=![jpg,gif]
                      WB_MaxFSize=10485760
                      -->
                      <!--WB_BeginTemplate-->
                      <html>
                      <head>
                      <title>$wbif["$wbv[image]"=""|Upload file|File uploaded]</title>
                      </head>
                      <body>
                      $wbif["$wbv[image]"=""|
                      <form action="$wbe[script_name]" method="post" ENCTYPE="multipart/form-data" id="UploadForm">
                      Select file (*.jpg;*.gif - max. 10MB): <input type="file" name="image" size="20"> 
                      <input type="submit" name="sButt" value="Upload" onclick="window.open('progress.wbsp?fid=$wbfulid[]','','width=200,height=100,toolbar=0,menubar=0,location=0,scroolbars=0');document.getElementById('UploadForm').submit();">
                      </form>
                      |
                      Open uploaded image<br><a href="$wbv[image]" target="_blank">$wbv[image]</a><br>
                      ]
                      </body>
                      </html>

Open in new window


Script progress.wbsp:
<html>
                      <head>
                      <meta http-equiv="refresh" content="1;url=$wbe[script_name]?fid=$wbv[fid]&pp=$wbcalc[$wbfup[$wbv[fid]]/$wbfut[$wbv[fid]]*100]">
                      </head>
                      <script language="javascript">
                      if($wbcalc[$wbfup[$wbv[fid]]/$wbfut[$wbv[fid]]*100]==0 && $wbv[pp]>0){window.close();}
                      window.focus(); #* Bring progress window on top upon reloading. To make this work in FireFox you must have "Allow scripts to: raise or lower windows" checked in advanced JavaScript preferences *#
                      </script>
                      <body>
                      Uploaded: $wbformat[$wbcalc[$wbfup[$wbv[fid]]/$wbfut[$wbv[fid]]*100]|0.00] %
                      </body>
                      </html>

Open in new window


Please note that both scripts contain only the code that was necessary for this example to work and that many things were left with default values, which is OK in this case, but in production environment it is highly recommended to define all system variables that you are actually using in your script.

So basically upload alone works using only one script – upload.wbsp. It contains a multipart HTML form to select the file for upload and send it to the same script (the script calls itself in forms ACTION parameter). When script receives the form variable with an uploaded file, it will check its size and type, and save it if everything is OK. Then the script will return an HTML page with a hyperlink to uploaded file to the visitor. This scenario is exactly the same with or without showing progress. The only WhizBase-related difference between upload form that can be tracked for upload progress and the one that can not is in defining a system variable WB_FULID to true.

Let’s comment that line:
WB_FULID=$wbif{"$wbv{image}"=""|t|f}

Open in new window

You notice decision structure ($WBIF) in a content of this variable setting its value to true only if form variable named “image” is empty. This is because we need to set WB_FULID (BTW – it is acronym for Form Upload ID) to true when upload form is opened, but before upload starts. This will set a unique ID for a particular form and a particular browser and that ID will be sent to the server together with form data so it will be used by WhizBase to save the progress info. Generated ID value can be retrieved using function $wbfulid[], and as you can see in the following line:
<input type="submit" name="sButt" value="Upload" onclick="window.open('progress.wbsp?fid=$wbfulid[]','','width=200,height=100,toolbar=0,menubar=0,location=0,scroolbars=0');document.getElementById('UploadForm').submit();">

Open in new window

We use it to pass form upload id to script progress.wbsp as variable named “fid”. This variable will be used in script progress.wbsp to retrieve progress data for exact upload session from WhizBase server.
All the action for showing the progress is located in this particular line:
Uploaded: $wbformat[$wbcalc[$wbfup[$wbv[fid]]/$wbfut[$wbv[fid]]*100]|0.00] %

Open in new window

Function $wbformat is used for showing progress percentage in proper format, and $wbcalc is used to calculate the percentage. But the real thing is retrieved by these two functions –
$wbfup – returns the number of currently uploaded bytes
and
$wbfut – returns the total size of upload

Note that both functions use the same argument - the value of form variable “fid” ($wbv[fid]) sent from script “upload.wbsp” on form submission. So the principle is very simple – use one script to upload the file(s), pass the generated form upload id (value returned by $wbfulid[] function) to the other script that will repeatedly retrieve number of uploaded bytes (for that particular form upload id) until upload is completed. Repetition is generated with simplest HTML meta tag:
<meta http-equiv="refresh" content="1;url=$wbe[script_name]?fid=$wbv[fid]&pp=$wbcalc[$wbfup[$wbv[fid]]/$wbfut[$wbv[fid]]*100]">

Open in new window

but therefore we had to close the window upon completion to avoid unnecessary traffic.
This line contains the code for closing window:
if($wbcalc[$wbfup[$wbv[fid]]/$wbfut[$wbv[fid]]*100]==0 && $wbv[pp]>0){window.close();}

Open in new window

so you can see a great example of mixing WhizBase code with JavaScript – “if” command on the left is still standard JavaScript statement, but it contains server-side WhizBase code that will never reach the client. Actually what the browser will receive is something like:
if(25.5==0 && 23.91>0){window.close();}

Open in new window

and will not close the window until it receives:
if(0==0 && 100>0){window.close();}

Open in new window

which will mean that upload is finished and progress data for upload session with particular form upload id is deleted. We added form variable “pp” ($wbv[pp]) to avoid closing progress window at the very beginning (with large files and slower connection you'll get 0% uploaded for first few seconds).

As you can see from the example above, showing an upload progress in WhizBase does not require any programming, but a simple calculation of two values provided by the server. This can also be accomplished using classic programming languages (like ASP, PHP, Perl, etc.) but it would require serious programming knowledge and much, much more code. On the other hand, to use this you must have WhizBase installed on your web server, and it is not as common as the mentioned programming languages.
2
3,080 Views

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.