Tutorial 4: Implementing a Progress Bar
The objective of this tutorial is to:
Demonstrate how to utilize the Upload control, UploadProgress component and the State Server in order to implement a progress bar.
To implement a progress bar you will need to have three elements: an html Input Form; a Progress Bar ASP page; and a Submit Action ASP page. These elements utilize the Dundas Upload control to gather the upload data and POST the upload operation details to the State Server. The State Server (StateServer.exe) is responsible for storing upload progress information which can then be updated and retrieved using an instance of either the UploadProgress component or the Upload control. The purpose of the Upload Progress component is to create unique Progress IDs, retrieve the progress information from the State Server and also delete information stored at the State Server when an upload is finished.
To use a progress bar you must perform the following actions for these three required items:
Input Form
Before submitting the form data the developer must create an instance of the Upload Progress component (the ProgID is "Dundas.UploadProgress) and request a new Progress ID.
Open the Progress Bar window and pass this Progress ID as a parameter.
- Submit the form data, once again passing this Progress ID as a parameter to the Submit Action ASP page.
Progress Bar ASP
This page should be refreshed (e.g. every two seconds).
The progress information is accessed by using an instance of the Upload Progress component along with the Progress ID passed to this page by the Input Form. To access the upload data set the ProgressID property of the Upload Progress instance to the passed Progress ID, call the GetProgress method and then utilize the TotalSize, UploadedSize and PercentCompleted properties.
The state information must be deleted when the upload operation is either completed or an error occurs (an exception will be thrown). To delete the upload information at the State Server just call the DeleteProgress method of the Upload Progress instance.
- The window may be closed when the upload reaches either 100% or an error occurs.
Submit Action ASP
- While uploading the data the Upload control (the ProgID is "Dundas.Upload.2") needs to post the progress status of the upload operation to the State Server. To accomplish this just set the ProgressID property of the control instance to the passed Progress ID.
How you implement these steps is totally up to you. If you require more
detailed instructions on utilizing a progress bar then refer to the following
or see the fully commented sample code.
NOTE:
You MUST USE
an <%@ENABLESESSIONSTATE = FALSE%> statement at the top of these
ASP pages so that more than one ASP page will be processed at the same
time.
Detailed Instructions
Create a main ASP page (we will call this page "main.asp"). This page must:
Have a form with an EncType of "multipart/form-data". This form needs to have one or more file input boxes for the uploading of data.
POST the data to a secondary page (we will call this page "process.asp").
Create an instance of the UploadProgress component before POSTING the data (the ProgID is "Dundas.UploadProgress)." Once this is done you must then obtain a new Progress ID (which uniquely identifies each upload operation) by calling the GetNewProgressID method of the UploadProgress component.
Pass this Progress ID to process.asp when POSTING the data (how this is done is up to you). In the following example we accomplish this by using a standard form button (instead of a "submit" button) and we specify a client-side function for the OnClick event. In this function we use "document.form.action" and "document.form.submit" statements to submit the form data to process.asp (after opening the progressbar.asp window --> see the next step). Note that the "action statement" uses a querystring to pass the Process ID to process.asp.
- Create the progress bar window (before POSTING the data). This window is an ASP page (let's call it "progressbar.asp") and once again you HAVE to let this page know what the Progress ID is (which you obtained from the UploadProgress component). We accomplish this by using a "window.open" statement in our form button's OnClick event. Note that this "window.open" statement uses a querystring to pass this Progress ID.
Create the page which will process the data (process.asp). This page must:
- Utilize the passed Progress ID and set the ProgressID property of the Upload control to this Progress ID BEFORE calling either the Save, SaveToMemory or GetNextFile method. Once this is done you can proceed with the uploading of data. By setting this property the Upload control instance will continuously update the State Server with upload operation details, which can then be retrieved via the Progress Upload component in the progressbar.asp page.
Create the progress bar window via an ASP page ("progressbar.asp"). This page must:
Be able to display the amount of data which has currently been uploaded. How you accomplish this is up to you. Note that the following sample code uses embedded tables with differing colors to accomplish this.
Be refreshed, for example, every two (2) seconds. You can use a meta refresh tag for this.
Retrieve details concerning the upload operation. This is accomplished by creating an instance of the UploadProgress component, setting its ProgressID property to the Progress ID passed by main.asp, calling the GetProgress method and then utilizing the TotalSize, UploadedSize and PercentCompleted properties. Every time the page is refreshed you can use these properties to update your "progess bar".
If the State Server (StateServer.exe) is located on another machine compared to this ASP page then you must set the StateServer property of the UploadProgress and Upload objects to the IP address of the machine where the State Server is lcoated. If you have set the "Port" property of the State Server to something other than the default then you must set the StateServerPort property of the UploadProgress and Upload objects to the same port.
Delete the progress information once the upload operation is cancelled or completed. This is done by calling the DeleteProgress method of the UploadProgress component.
- You can close the window once the upload is completed or cancelled. How you do this is up to you. Note that the following sample code accomplishes this through client-side script.
NOTE: You
MUST USE an <%@ENABLESESSIONSTATE
= FALSE%> statement at the top of these ASP pages so that more than
one ASP page will be processed at the same time.
Assumptions for the following Sample Code
There are three pages to this sample: main.asp, progressbar.asp and process.asp (as described above).
- The form in main.asp is POSTING data to process.asp with an EncType of "mulitpart/form-data". It is assumed that this form has one file input box named "file1".
main.asp
<%@ENABLESESSIONSTATE=FALSE%> 'turn off session state support so that more than
' one ASP page can be processed at the same time.
<html><head></head>
<body color="black" bgcolor="white">
<%
dim objUploadProgress 'UploadProgress component instance
dim ProgressID 'new progress (state) id - uniquely identifies this upload operation
'create an instance of the UploadProgress component
set objUploadProgress = server.CreateObject("Dundas.UploadProgress")
'we must retrieve a new progress id, which is passed to both process.asp and progressbar.asp
ProgressID = objUploadProgress.GetNewProgressID
%>
<Script language="javascript">
<!--
//retrieve the State (Progress) ID to be passed to progressbar.asp
// and process.asp
ProgressID=<%=ProgressID%>;
function Upload()
//this javascript function runs when the user clicks on the form's button.
//it opens the progressbar.asp window and then submits the form data to process.asp
{
if (ProgressID != -1){
//only open progressbar.asp window if there is a valid id. We will center this progress bar as well.
Param = "SCROLLBARS=no,RESIZABLE=no, TOOLBAR=no,STATUS=no,MENUBAR=no,WIDTH=400,HEIGHT=100";
Param += ",TOP=" + String(window.screen.Height/2 - 50);
Param += ",LEFT=" + String(window.screen.Width/2 - 200);
//note that we pass the Progress ID to progressbar.asp
window.open("ProgressBar.asp?ProgressID=<%=ProgressID%>", null, Param);
}
//now that progress bar window is open submit the form data to Process.asp, passing
// the ProgressID as a querystring parameter
document.frmMain.action = "Process.asp?ProgressID=<%=ProgressID%>"
document.frmMain.submit();
}
//-->
</Script>
<form name="frmMain" action="process.asp" enctype="multipart/form-data" method="post">
Please choose a file to be uploaded: <input type="file" name="File1">
<br><br>
<!--Note that we use a standard button and not a submit button. We do this so that
we can open the progress bar window (Progress.asp) as well as pass the submitted
data to the page which processes the submitted form data -->
<input type="button" name="submit1" value="Upload File" OnClick="Upload()">
</form>
</body>
</html>
process.asp
<%@ENABLESESSIONSTATE=FALSE%>
<%'we just disabled session state so that more than one asp page can be processed at once
On Error Resume Next
'create an instance of the Upload component
Dim objUpload
Set objUpload = Server.CreateObject("Dundas.Upload.2")
'set the ProgressID property of the control to the state (progress) ID which
' was obtained in main.asp and passed as a querystring. By setting this property
' the Upload control instance will continuously update the State Server with
' information concerning this particular upload operation.
objUpload.ProgressID = Request.QueryString("ProgressID")
'set maximum file size to 2 MByte
objUpload.MaxFileSize = 200000000
'save uploaded data to memory, and then check for errors
objUpload.SaveToMemory
'if an error occurred we will close the progressbar.asp window by
' deleting the state information at the State Server
If Err.Number <> 0 Then
dim objUploadProgress
set objUploadProgress = server.CreateObject("Dundas.UploadProgress")
objUploadProgress.ProgressID = Request.QueryString("ProgressID")
objUploadProgress.DeleteProgress
End If
'release resources
Set objUpload = Nothing
%>
progressbar.asp
<%@ENABLESESSIONSTATE=FALSE%>
<html><head>
<meta http-equiv=refresh content="1,ProgressBar.asp?ProgressID=<%=Request.QueryString("ProgressID")%>">
</head>
<%
On Error Resume Next
'force this page to expire immediately
Response.Expires = -10000
'create an instance of the UploadProgress component
Set objUploadProgress = Server.CreateObject("Dundas.UploadProgress")
'if the State Server is running on a different machine compared to these ASP pages
' then this is where you would have to set the State Server's IP address
'objUploadProgress.StateServer = "127.0.0.1"
'retrieve progress data from the StateServer
objUploadProgress.ProgressID = Request.QueryString("ProgressID")
objUploadProgress.GetProgress
Percentage = objUploadProgress.PercentCompleted
TotalSize = objUploadProgress.TotalSize
UploadedSize = objUploadProgress.UploadedSize
'if there is no data yet for this particular upload operation then these proeprties will
' be set to negative one (-1)
If TotalSize = -1 OR UploadedSize = -1 Then
'if no data yet set to zero, since we do not want to display negative one
TotalSize = 0
UploadedSize = 0
End If
'If an error occurs set the percentage value to -1. The client-side script below
' will close the progress bar window when this occurs. Note that a negative one will
' be encountered since we delete the state information for this particular upload
' operation when 100% is reached, so the next call to the GetProgress method will
' result in an exception being raised, thereby resulting in this window being closed.
If Err.number <> 0 Then
Percentage = -1
End If
'delete progress data when we hit 100%
If objUploadProgress.PercentCompleted = 100 Then
objUploadProgress.DeleteProgress
End If
'release resources
Set objUploadProgress = Nothing
%>
<script>
<!-- set a variable to the percent complete -->
var val = <%=Percentage%>;
// If there are any errors or upload is complete then close window
if(val == -1){
top.close();
}
</script>
<body>
<!-- use embedded tables with different color to simulate a progress bar -->
<table border="1" width="100%">
<tr>
<td>
<table ID="Prog" border="0" width="<%=Percentage%>%" bgcolor="#FF0000">
<tr>
<td width="100%"> </td>
</tr>
</table>
</td>
</tr>
</table>
</body>
<P align="center"><FONT size="2">
<%=Percentage%>% (Uploaded <%=UploadedSize%> of <%=TotalSize%> bytes)
</FONT></P>
</html>