Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Monday, July 13, 2009 12:50 AM
I want to update the text of a Label control on the client browser (ideally on each iteration of a "for loop" or at set time intervals) whilst performing some process on the server, which could be time consuming. However, I would always know how many iterations are required up front, so I don't just want to show "Please wait ..."; but rather: 3 out of 10 for example.
I am using VS 2008, C#, and ASP.NET 3.5 SP1, which has AJAX Extensions but I do not have the Toolkit installed. Also, I do not have any JavaScript knowledge.
Here's my LoopTest.aspx page:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<p>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:Button ID="btnLoop"
runat="server"
Text="Button"
onclick="btnLoop_Click" />
<asp:Label ID="lblMessage" runat="server" ></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</p>
<p>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" >
<ProgressTemplate>
<asp:Label ID="lblProgress" runat="server" ></asp:Label>
Please wait ...
</ProgressTemplate>
</asp:UpdateProgress>
</p>
Here's my code behind page:
protected void btnLoop_Click(object sender, EventArgs e)
{
Label lblProgress = (Label)UpdateProgress1.FindControl("lblProgress");
for (int i = 0; i <= 10; i++)
{
lblProgress.Text = i.ToString();
lblMessage.Text = i.ToString();
System.Threading.Thread.Sleep(1000); // simulating delay whilst testing
}
}
As you can see, I would like to update either lblProgress or lblMessage (only one is required, but they are here as I try different approaches) on each iteration of the for loop to the client browser. However, the code above does not update the Label controls text property until the loop has finished.
Any ideas? Thanks.
PS. I've searched for hours on providing feedback to users, but most solutions show outdated techniques (before AJAX Extensions) or heaps of pure JavaScript code. Hence, any suggestions on the most elegant, straight forward and latest way to provide "live feedback" to an end user is welcome.
All replies (7)
Thursday, July 16, 2009 11:04 PM ✅Answered
Hi Keep it Simple,
If you test my script code, you can understand how to change the Loop by yourself. A simply way is defining the range and the duration yourself like this:
script
var index = 0;
var range = "<%=iRange %>";
var duration = "<%=iDuration %>";
function changeText() {
index = index + 1;
if (index <= duration) {
$get('Label1').innerHTML = index;
window.setTimeout("changeText()", range);
}
}
code-behind
Public Partial Class TestUpdateProgress
Inherits System.Web.UI.Page
Public iRange As Integer = 1000
Public iDuration As Integer = 20
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Protected Sub btnLoop_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLoop.Click
System.Threading.Thread.Sleep(iRange * iDuration)
End Sub
End Class
Have this helped?
Best regards,
Zhi-Qiang Ni
Friday, July 17, 2009 6:11 AM ✅Answered
Hi Keep it Simple,
I have replied that we can not change the Server control property value in the For Loop as the value can only be seen after the rendered phase. So, we can not calculate each loop’s duration but the whole time of the Updating process. Then, in the client script, we can set a long enough duration for the text changing. The UpdatePanelAnimation would be hidden automatically after the UpdatePanel is updated.
Best regards,
Zhi-Qiang Ni
Tuesday, July 14, 2009 4:38 AM
go through this
http://www.asp.net/learn/ajax-videos/video-123.aspx
Tuesday, July 14, 2009 9:18 PM
Thanks. I want more than just an animated GIF and "Please wait " static text.
Is there a way to update the Label text in an UpdateProgress control in each iteration of a FOR LOOP running on the server?
Thursday, July 16, 2009 4:24 AM
Hi,
I think it is impossible to achieve any dynamically change of server controls in the For Loop. Because the For Loop is in the Button’s click event which is belong to the UpdatePanel’s updating process, the change of the server control property can only be seen after this post back.
To achieve your goal, we need to use the UpdatePanelAnimationExtender and a client recursive function like this:
.aspx file
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="TestUpdateProgress.aspx.vb"
Inherits="SoluTest_UpdateAnimation.TestUpdateProgress" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!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 runat="server">
<title></title>
<script type="text/javascript">
var index = 0;
var range = 1000;
var duration = 5;
function changeText() {
index = index + 1;
if (index <= duration) {
$get('Label1').innerHTML = index;
window.setTimeout("changeText()", range);
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Button ID="btnLoop" runat="server" Text="Button" OnClick="btnLoop_Click" />
<asp:Label ID="lblMessage" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Panel ID="pnlUpdateProgress" runat="server" Style="display: none" Height="72px"
Width="220px" BackColor="#99FF66">
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<br />
The UpdateProgress
</asp:Panel>
<ajaxToolkit:UpdatePanelAnimationExtender ID="upae" BehaviorID="animation" runat="server"
TargetControlID="UpdatePanel1">
<Animations>
<OnUpdating>
<Sequence>
<StyleAction AnimationTarget="pnlUpdateProgress" Attribute="display" Value="block"/>
<ScriptAction Script="changeText()"/>
</Sequence>
</OnUpdating>
<OnUpdated>
<Sequence>
<StyleAction AnimationTarget="pnlUpdateProgress" Attribute="display" Value="none"/>
</Sequence>
</OnUpdated>
</Animations>
</ajaxToolkit:UpdatePanelAnimationExtender>
</div>
</form>
</body>
</html>
.aspx.vb file
Protected Sub btnLoop_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnLoop.Click
System.Threading.Thread.Sleep(5000)
End Sub
Here is a good Progress sample only written in JavaScript: http://www.javascriptkit.com/script/script2/progressbar.shtml
Have my suggestion helped?
Best regards,
Zhi-Qiang Ni
Thursday, July 16, 2009 10:08 PM
Zhi-Qiang, thanks for the reply!
I have tested your suggested code but it just counts up to 5 and then stops. If I have a For loop on ther server with 20 iterations, it stops at 5 and is "out of synch" with the server loop.
Hence, it does not achieve the desired goal of dynamically updating a Label text property whilst in a For loop running on the server - which I guess is inline with your opening comment about it not being possible.
Perhaps in the next version release of AJAX ...
Thursday, July 16, 2009 11:59 PM
The revised simulated test code with Sleep in the button click event works OK.
In a real situation, where you kick off some task such as sending an email per each iteration (or some other process), the time it takes to complete the task may take less than a second and in some iterations many seconds depending on how busy the web server and database is etc.
Unless, I'm missing something obvious, how would you factor that in within the FOR loop on the server without the System.Threading.Thread.Sleep() function call?
for (int i = 0; i <= 20; i++)
{
// do some variable time task here e.g. send email and then update database
SendMail();
Label1.Text = "Processed record number: " + i.ToString();
}
In other words, each iteration in the FOR loop takes a different amount of time
Iteration 1 takes 0.7 seconds
Iteration 2 takes 4.4 seconds
Iteration 3 takes 1.8 seconds and so on ...
Would that cause the JavaScript code to be out of synch with the ASP.NET code? Thanks ...