UploadFileWithAjaxProgressBar.aspx Font Size:
Source Code Viewer Files: UploadFileWithAjaxProgressBar.aspx   UploadFileWithAjaxProgressBar.aspx.vb   
JavaScript File: JSCore.js   
Config File: Web.Config   
CSS File: ExamplesStyle.css   
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="UploadFileWithAjaxProgressBar.aspx.vb" Inherits="EAUploadExamples.UploadFileWithAjaxProgressBar" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>Upload file with ajax progress bar</title>
        <link rel="stylesheet" href="ExamplesStyle.css" />
        <script type="text/javascript" src="JSCore.js"></script>
        <script type="text/javascript">
            var nonMSDOMBrowser = (window.navigator.appName.toLowerCase().indexOf('explorer') == -1);
            
            // Referense to bug fix: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=705049&SiteID=1
            function ICallbackEventHandlerFix()
            {
                if (typeof (WebForm_CallbackComplete) == "function")
                {
                    // set the original version with fixed version
                    WebForm_CallbackComplete = WebForm_CallbackComplete_SyncFixed;                                  
                  
                }
            }
            
            function WebForm_CallbackComplete_SyncFixed()
            {
                  
                  // SyncFix: the original version uses "i" as global thereby resulting in javascript errors when "i" is used elsewhere in consuming pages
                  for (var i = 0; i < __pendingCallbacks.length; i++)
                  {
                      callbackObject = __pendingCallbacks[ i ];
                      //alert(callbackObject + " : " + callbackObject.xmlRequest + " : " + callbackObject.xmlRequest.readyState + " : " + callbackObject.xmlRequest.responseText);
                      if (callbackObject && callbackObject.xmlRequest && (callbackObject.xmlRequest.readyState == 4)) {
                           // the callback should be executed after releasing all resources 
                           // associated with this request. 
                           // Originally if the callback gets executed here and the callback 
                           // routine makes another ASP.NET ajax request then the pending slots and
                           // pending callbacks array gets messed up since the slot is not released
                           // before the next ASP.NET request comes.
                           // FIX: This statement has been moved below
                           // WebForm_ExecuteCallback(callbackObject);
                           if (!__pendingCallbacks[ i ].async)
                           {
                             __synchronousCallBackIndex = -1;
                           }
                           __pendingCallbacks[i] = null;

                           var callbackFrameID = "__CALLBACKFRAME" + i;
                           var xmlRequestFrame = document.getElementById(callbackFrameID);
                           if (xmlRequestFrame)
                           {
                             xmlRequestFrame.parentNode.removeChild(xmlRequestFrame);
                           } 
                           
                           // Trick for FireFox. Sometimes the first response is empty.
                           // So, we check that the current async request is upload request and if so call the server again.
                           if(nonMSDOMBrowser && isUploadRequest && callbackObject.xmlRequest.responseText == "" && UploadId != "")
                           {
                             CallServer(UploadId);                             
                             return;
                           }                      
                       
                           // SyncFix: the following statement has been moved down from above;
                           WebForm_ExecuteCallback(callbackObject);
                       
                      }
                 }
            }
            
            // Below code for upload management.
            
            // Determine id of asp.net controls on client side.
            var uploadButtonID = '<% = Button1.ClientID %>';            
            var responseLabelID = '<% = lblResponse.ClientID %>';
            var UploadId;
            var isUploadRequest;
            var isUploadCanceled = false;            
            
            function doUpload()
            {
                // Get an unique identifier that will be used by EAUploadModule 
                // for creating a new instance of Upload class.
                // You should provide an UploadId for file processing page and
                // for page that is used for retrieving a status information.
                // EAUpload retrieves this value and uses it
                // as an unique identifier of an Upload class instance.
                // So, now we can get an access to required Upload object by this id 
                // from any page within the application.    
                UploadId = GetUploadId(); // GetUploadId() defined in JSCore.js
                
                var Form = document.getElementById("Form1");
                Form.action = RefreshQueryString(Form.action, UploadId);                
                isUploadRequest = true;
                isUploadCanceled = false
                document.getElementById(responseLabelID).innerHTML = "";    
                
                // Recieve a status information through asynchronous request.
                CallServer(UploadId);                                
                                
                document.getElementById("cancelButton").style.display = "block";
                document.getElementById(uploadButtonID).style.display = "none";
                
                return true;
            
            }
            
            // Terminates an upload process
            function cancelUpload()
            {
                isUploadCanceled = true;
                
                if (window.stop)
                {
                    window.stop();
                }
                else
                {
                    window.document.execCommand("Stop");                
                }
                
                CallServer("DELETE--sep--" + UploadId);
                
                isUploadRequest = false;
                UploadId = "";
                
                document.getElementById("StatusInfo").style.display = "none";
                document.getElementById("FileList").style.display = "block";
                
                document.getElementById("cancelButton").style.display = "none";
                document.getElementById(uploadButtonID).style.display = "block";        
                    
            }
                
            // Handles an event that is occurred when a status information is received
            // and refreshes a status information on the page.            
            // "response" - a string response from a web server
            function OnResponseLoaded(response)
            {
                if(isUploadCanceled)
                {
                    return;
                }
                
                var StatusInfoOutput = document.getElementById("StatusInfo");
                
                if (response && response != "")
                {
                    if(response == "DELETED")
                    {
                        return;
                    }
                    
                    // Note! If ProcessRequestOnError parameter or property is set to "false" 
                    // then there is now way to display a response to the client(browser).
                    // As a matter of fact, the server will receive 50 - 100 Kb only before upload is canceled.
                    if(response.indexOf("FAILED") != -1)
                    {
                        var args = response.split("--sep--");
                        
                        alert(args[1]);
                        
                        cancelUpload();                
                        
                        return;
                    }
                    
                    if (StatusInfoOutput.style.display == 'none')
                    {
                        document.getElementById("FileList").style.display = "none";
                        StatusInfoOutput.style.display = 'block';                        
                    }
                    
                    // Convert JSON string to JavaScript object.
                    // JSONtoJSObject is defined in JSCore.js
                    var StatusInfo = JSONtoJSObject(response);
                    
                    if (typeof(StatusInfo.PercentsDone) != 'undefined') // Checking that the response is converted to the JavaScript object correct.
                    {
                        document.getElementById('progressBar').style.width = StatusInfo.PercentsDone + '%';
                        document.getElementById('progressPercentsDone').innerHTML = StatusInfo.PercentsDone + '%';
                        
                        var htmlString = 'Uploaded ' + Math.round(StatusInfo.UploadedBytes / 1024) + ' KB of ' + Math.round(StatusInfo.TotalBytes / 1024) + ' KB<br/>';
                        htmlString += 'Time left: ' + StatusInfo.RemainingTime + ' sec<br/>';
                        htmlString += 'Transfer rate: ' + Math.round((StatusInfo.BytesPerSecondAvg / 1024)*100)/100 + ' KB/s<br/>';
                        htmlString += 'Current uploading file: ' + StatusInfo.CurrentFileName + '<br/><br/>';
                        
                        document.getElementById('progressTextInfo').innerHTML = htmlString;
                        
                        if (StatusInfo.State == 'Complete')
                        {                                            
                            isUploadRequest = false;
                            UploadId = "";                        
                            
                            return;
                        }                        
                            
                    }
                    else
                    {
                        StatusInfoOutput.innerHTML = response;                        
                        return;
                    }                
                }
                else
                {
                    return;
                }                
                                                                
                // Set timeout for the next server call.
                setTimeout('CallServer(' + StatusInfo.UploadID + ', "")', 500);                                
                
            }        
           
        </script>
    </head>
    <body onload="ICallbackEventHandlerFix();">
        <form id="Form1" method="post" runat="server" enctype="multipart/form-data">
            This example demonstrates how to upload files to a web server and display a 
            status information of an upload process. A status information is received asynchronous in JavaScript Object Notation (JSON, for more 
            information see <a href="http://msdn2.microsoft.com/en-us/library/bb299886.aspx">An 
                Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET</a>. ICallBackEventHandler is used for asynchronous call to the server.
            <br />
            Also this example demonstrates how to display to users an error message during upload. Specifically, the case
            when need to dispaly an error message about <b>restriction of file size</b> without reading the whole request.
            <br />
            Select a file greather than MaxRequestLength property value and see example in action.
            <br />
            <br />
            All uploaded files will be stored to the "UploadedFiles" folder that is located 
            in the root directory of an examples.<br/>
            You should grant write access to "UploadedFiles" folder to the ASP.NET process identity(typically {MACHINE}\ASPNET on IIS 5<BR>
            or Network Service on IIS 6).
            <br/>        
            <b>NOTE:</b> If you run this example on the local machine, select larg files(greater than 100MB) to 
            see a progress bar in action.
            <br />
            <br />            
            <table id="FileList">
                <tr>
                    <td>File 1:</td>
                    <td><input type="file" name="File_1" size="40"></td>
                </tr>
                <tr>
                    <td>File 2:</td>
                    <td><input type="file" name="File_2" size="40"></td>
                </tr>
            </table>
            <div id="StatusInfo" style="DISPLAY: none; FONT-SIZE: small">
                <div style="BORDER-RIGHT: #000000 1px solid; BORDER-TOP: #000000 1px solid; PADDING-LEFT: 5px; BORDER-LEFT: #000000 1px solid; WIDTH: 500px; LINE-HEIGHT: 20px; BORDER-BOTTOM: #000000 1px solid; BACKGROUND-COLOR: #d4d0c8">
                    <table style="WIDTH: 100%">
                        <tr>
                            <td style="BORDER-RIGHT: #0000ff 1px solid; BORDER-TOP: #0000ff 1px solid; BORDER-LEFT: #0000ff 1px solid; WIDTH: 440px; BORDER-BOTTOM: #0000ff 1px solid; HEIGHT: 15px">
                                <div id="progressBar" style="BACKGROUND: #009900; WIDTH: 0%; HEIGHT: 15px"></div>
                            </td>
                            <td id="progressPercentsDone" style="WIDTH: 50px; TEXT-ALIGN: center">
                            </td>
                        </tr>
                    </table>
                    <div id="progressTextInfo">
                    </div>
                </div>
            </div>            
            <br />
            <asp:Button ID="Button1" runat="server" Text="Upload" OnClientClick="return doUpload();" OnClick="Button1_Click" />
            <a id="cancelButton" onclick="cancelUpload()" style="display: none"><img src="images/cancel_button.gif" border="0"></a>
            <br />
            <br />
            <asp:Label id="lblResponse" runat="server"></asp:Label>
        </form>
        <hr>
        <a href="default.aspx" title="All examples">Other examples</a>
        <p style="FONT-WEIGHT: bold">
            This example doesn't work correctly in: Safari<br />
            Suggestion: detect a browser and if it's Safary display the progress indicator in a new window.            
        </p>
        <p>
            Used files: Bin\EasyAlgo.EAUpload.dll, web.config, UploadFileWithAjaxProgressBar.aspx, 
            UploadFileWithAjaxProgressBar.aspx.vb, JSCore.js, ExamplesStyle.css [Optional]
        </p>
    </body>
</html>