<%@ Page language="c#" Codebehind="AjaxFileUploadWithAjaxProgressBar.aspx.cs" AutoEventWireup="True" Inherits="EAUploadExamples.AjaxFileUploadWithAjaxProgressBar" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML xmlns="http://www.w3.org/1999/xhtml" >
<HEAD>
<title>Upload with 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 ];
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 isProgressDisplayEnded = false;
var isIFrameResponseLoaded = false;
var isUploadCanceled = false;
var ensureProgressRendered;
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);
Form.setAttribute('target', "iFrameUploader");
// Set flags.
isProgressDisplayEnded = false;
isIFrameResponseLoaded = false;
isUploadRequest = true;
isUploadCanceled = false;
document.getElementById(responseLabelID).innerHTML = "";
// Below code for non IE browsers.
// For IE we should define onload handler in html element.
var iFrame = document.getElementById("iFrameUploader");
if(nonMSDOMBrowser)
{
iFrame.onload = OnIFrameResponseLoaded;
}
// 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;
try
{
var iFrame = document.getElementById("iFrameUploader");
var iFrameDocument = GetIFrameDocumentObject(iFrame);
if (window.stop)
{
iFrame.contentWindow.stop();
}
else
{
iFrameDocument.execCommand("Stop");
}
}
catch(exception)
{}
if (window.stop)
{
window.stop();
}
else
{
window.document.execCommand("Stop");
}
isUploadRequest = false;
UploadId = "";
ShowHidePageElements();
}
// 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.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 = "";
// Here we check whether async upload request is loaded or not.
// And if it's not define delayed handling.
// Below code for non IE browsers.
// For IE we should define onload handler in html element.
if(isIFrameResponseLoaded)
{
// Ensure that the progress indicator is fully rendered.
setTimeout("ParseIFrameResponse()", 200);
}
else
{
if(nonMSDOMBrowser)
{
var iFrame = document.getElementById("iFrameUploader");
iFrame.onload = ParseIFrameResponse;
}
}
isProgressDisplayEnded = true;
return;
}
}
else
{
StatusInfoOutput.innerHTML = response;
isProgressDisplayEnded = true;
return;
}
}
else
{
StatusInfoOutput.innerHTML = 'The progress cannot be displayed!!!';
isProgressDisplayEnded = true;
return;
}
// Set timeout for the next server call.
setTimeout('CallServer(' + StatusInfo.UploadID + ', "")', 500);
}
function GetIFrameDocumentObject(iFrameObject)
{
if (iFrameObject.contentWindow && iFrameObject.contentWindow.document)
{
return iFrameObject.contentWindow.document;
}
else if (iFrameObject.contentDocument)
{
return iFrameObject.contentDocument;
}
else if (iFrameObject.document)
{
return iFrameObject.document;
}
}
function OnIFrameResponseLoaded()
{
isIFrameResponseLoaded = true;
if(!nonMSDOMBrowser && isProgressDisplayEnded)
{
ParseIFrameResponse();
}
}
function ParseIFrameResponse()
{
var iFrame = document.getElementById("iFrameUploader");
var iFrameDocument = GetIFrameDocumentObject(iFrame);
var iFrameResponse = iFrameDocument.getElementById(responseLabelID);
if(iFrameResponse)
{
document.getElementById(responseLabelID).innerHTML = iFrameResponse.innerHTML;
}
ShowHidePageElements();
iFrameDocument.getElementsByTagName("body")[0].innerHTML = "";
}
function ShowHidePageElements()
{
document.getElementById("StatusInfo").style.display = "none";
document.getElementById("FileList").style.display = "block";
document.getElementById("cancelButton").style.display = "none";
document.getElementById(uploadButtonID).style.display = "block";
}
</script>
</HEAD>
<body onload="ICallbackEventHandlerFix();">
<form id="Form1" method="post" runat="server" enctype="multipart/form-data">
This example demonstrates how to upload file without page reload(<b>Ajax file upload</b>). All requests
are sent to the server asynchronous through an iframe.<br />
A status information is received 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 />
<b>This example allows to upload files with total volume less than 50 MB.</b>
<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>
<iframe id="iFrameUploader" name="iFrameUploader" onload="OnIFrameResponseLoaded();" style="display:none;"></iframe>
<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 target="_blank" href="http://www.easyalgo.com/quickstart/util/srcview.aspx?path=/Examples/EAUpload/AjaxFileUploadWithAjaxProgressBar.src">View C Sharp source code</a>
<a target="_blank" href="http://www.easyalgo.com/quickstart/util/srcview.aspx?path=/Examples/EAUpload/VBNET/AjaxFileUploadWithAjaxProgressBar.src">View VB NET source code</a>
<p>
If you need help and advice in understanding how to implement this example please write to us <a href="mailto:support@easyalgo.com">support@easyalgo.com</a>
</p>
</body>
</HTML>