Showing posts with label content. Show all posts
Showing posts with label content. Show all posts

Wednesday, March 21, 2012

Delaying Content Load using Timer and UpdatePanel

I've created a custom template control that I'm trying to use to delay content loading on a page for long running controls.

Here:

1public sealed class DelayedContentLoader : WebControl, INamingContainer
2 {
3private MultiView mvContent =new MultiView();
45private int interval = 10000;
6public int Interval
7 {
8get {return interval; }
9set { interval =value; }
10 }
1112public delegate bool LoadContentHandler();
13public LoadContentHandler OnLoadContent;
1415private ITemplate loadingTemplate;
16 [TemplateContainer(typeof(LoadingView))]
17public ITemplate LoadingTemplate
18 {
19get {return loadingTemplate; }
20set { loadingTemplate =value; }
21 }
2223private ITemplate loadFailedTemplate;
24 [TemplateContainer(typeof(LoadFailedView))]
25public ITemplate LoadFailedTemplate
26 {
27get {return loadFailedTemplate; }
28set { loadFailedTemplate =value; }
29 }
3031private ITemplate contentTemplate;
32 [TemplateContainer(typeof(ContentView))]
33public ITemplate ContentTemplate
34 {
35get {return contentTemplate; }
36set { contentTemplate =value; }
37 }
3839protected override void OnInit(EventArgs e)
40 {
41if (loadingTemplate !=null)
42 {
43 LoadingView loadingViewContainer =new LoadingView();
44 loadingTemplate.InstantiateIn(loadingViewContainer);
45 mvContent.Views.Add(loadingViewContainer);
46 }
4748if (contentTemplate !=null)
49 {
50 ContentView contentViewContainer =new ContentView();
51 contentTemplate.InstantiateIn(contentViewContainer);
52 mvContent.Views.Add(contentViewContainer);
53 }
54else
55 throw new Exception("A Content Template must be specified.");
5657if (loadFailedTemplate !=null)
58 {
59 LoadFailedView loadFailedViewContainer =new LoadFailedView();
60 loadFailedTemplate.InstantiateIn(loadFailedViewContainer);
61 mvContent.Views.Add(loadFailedViewContainer);
62 }
63 }
6465protected override void OnLoad(EventArgs e)
66 {
67 UpdatePanel updatePanel =new UpdatePanel();
68 updatePanel.UpdateMode = UpdatePanelUpdateMode.Always;
6970 mvContent.ActiveViewIndex = 0;
7172 updatePanel.ContentTemplateContainer.Controls.Add(mvContent);
7374 Timer timer =new Timer();
75 timer.ID ="timerDelayedContentLoader";
76 timer.Interval = interval;
77 timer.Tick +=new EventHandler(timer_Tick);
7879 updatePanel.ContentTemplateContainer.Controls.Add(timer);
8081 Controls.Add(updatePanel);
82 }
8384public override Control FindControl(string id)
85 {
86 Control ctrl = mvContent.Views[1].FindControl(id);
87if (ctrl !=null)
88return ctrl;
8990 ctrl = mvContent.Views[2].FindControl(id);
91if (ctrl !=null)
92return ctrl;
9394 ctrl = mvContent.Views[0].FindControl(id);
9596return ctrl;
97 }
9899private void timer_Tick(object sender, EventArgs e)
100 {
101bool loadedContentSuccessfully =false;
102if (OnLoadContent !=null)
103 loadedContentSuccessfully = OnLoadContent();
104105// Stop the timer.106 Timer timer = FindControl("timerDelayedContentLoader")as Timer;
107if (timer !=null)
108 timer.Enabled =false;
109110int visiblePlh = loadedContentSuccessfully ? 1 : 2;
111 mvContent.ActiveViewIndex = visiblePlh;
112 }
113 }

The control does work, but once the first 'panel' loads I'm getting this error:

Error: Sys.ScriptLoadFailedException: The script 'http://localhost:2059/WebResource.axd?d=2969z1Qx3dbsV5nCF1BRcXhpF5ub86-cDZ-FaGYdZEBQbKzZVJb7tl6DB7CRlXIMyp8MDajf0oi_5PQ_Zb35Pg2&t=633181289164114804' failed to load. Check for:
Inaccessible path.
Script errors. (IE) Enable 'Display a notification about every script error' under advanced settings.
Missing call to Sys.Application.notifyScriptLoaded().
Source File: http://localhost:2059/ScriptResource.axd?d=w7roB_KjU8DhSirRDxfFxPRhP-DUqImf_4Nd1a5Co3kx1o511QAFqGXxMtkfZR8UkArHbaLDYRdK8lHjJK-ARWQArhEXy5Ydco_GHuMUgH41&t=633120912402558276
Line: 3311

The error kills all of the JavaScript on the page - others delayed content loaders stop loading and all other AJAX stuff ceases to work. The line that is referenced is this line #10 below:

// MicrosoftAjax.js
// Microsoft AJAX Framework.
1function Sys$_ScriptLoader$_raiseError(multipleCallbacks) {
2 var callback = this._scriptLoadFailedCallback;
3 var scriptElement = this._currentTask.get_scriptElement();
4 this._stopLoading();
5
6 if(callback) {
7 callback(this, scriptElement, multipleCallbacks);
8 }
9 else {
10throw Sys._ScriptLoader._errorScriptLoadFailed(scriptElement.src, multipleCallbacks);
11 }
12 }

Is there anything that can be done here? By the way, this control is inside of a Web Part. If I remove all the Web Part stuff, I don't get the error but only one of my delayed content loading controls finishes loading.

Any help would be much appreciated.

Thanks!

Has anyone tried to do this?


Hi

Ok,Just do it like this:

<%@. Page Language="C#" %>

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

<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
}
</script>

<script type="text/javascript">
function delayLoad()
{
document.getElementById("<%= Button1.ClientID %>").click();
document.getElementById("<%= UpdateProgress1.ClientID %>").style.display = "block";
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body onload="setTimeout('delayLoad()',3000)">
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<div visible="true"><asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /></div>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
Waiting...........
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
</body>
</html>

Thanks:)


How is that the same as what I was trying to do? Unless you're saying I need to have my update panel's UpdateMode set to conditional. Are you?


Hi,

In my code,I delay by 3 second to load the content.

It's the same as following code:

<%@. Page Language="C#" %>

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

<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
}

protected void Timer1_Tick(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
Timer1.Enabled = false;
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<div visible="true">
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /></div>
<asp:Timer ID="Timer1" runat="server" Interval="3000" OnTick="Timer1_Tick">
</asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
Waiting...........
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</form>
</body>
</html>

A timer for an updatepanel.we can do it.

I know you just want to creat a contorl to include a updatepanel and a timer,I'll do it for you later.


OK

I have done it for you now.

bur I 'm using webcontrol rather than server control,I think it is more simple:)

The code :

The page:

<%@. Page Language="C#" %>

<%@. Register src="http://pics.10026.com/?src=WebUserControl5.ascx" TagName="WebUserControl5" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
protected bool WebUserControl5_1_LoadContent(object sender, EventArgs e)
{
try
{
((WebUserControl5)sender).myContent = "OK..........";
}
catch
{
return false;
}
return true;
}
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<uc1:WebUserControl5 ID="WebUserControl5_1" runat="server" OnLoadContent="WebUserControl5_1_LoadContent" />
</div>
<div>
<uc1:WebUserControl5 ID="WebUserControl5_2" runat="server" OnLoadContent="WebUserControl5_1_LoadContent" />
</div>
<div>
<uc1:WebUserControl5 ID="WebUserControl5_3" runat="server" OnLoadContent="WebUserControl5_1_LoadContent" />
</div>
<div>
<uc1:WebUserControl5 ID="WebUserControl5_4" runat="server" OnLoadContent="WebUserControl5_1_LoadContent" />
</div>
</form>
</body>
</html>

The control:

<%@. Control Language="C#" ClassName="WebUserControl5" %>

<script runat="server">
protected void Timer1_Tick(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
bool loadedContentSuccessfully = false;
if (LoadContent != null)
loadedContentSuccessfully = LoadContent(this,e);

// Stop the timer.
Timer1.Enabled = false;

int visiblePlh = loadedContentSuccessfully ? 1 : 2;
MultiView1.ActiveViewIndex = visiblePlh;
}

public delegate bool LoadContentHandler(object sender, EventArgs e);
public event LoadContentHandler LoadContent;
public string myContent
{
set
{
TextBox2.Text = value;
}
}
</script>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Timer ID="Timer1" runat="server" Interval="3000" OnTick="Timer1_Tick">
</asp:Timer>
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
<asp:View ID="LoadingView" runat="server">
Loading...........</asp:View>
<asp:View ID="ContentView" runat="server">
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox></asp:View>
<asp:View ID="LoadFailedView" runat="server">
Failed...........</asp:View>
</asp:MultiView>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
Waiting...........
</ProgressTemplate>
</asp:UpdateProgress>

Works cool.....:)

Thanks


Not exactly what I was looking for since I want to build something that's a bit more re-usable than a simple ASCX. Another issue I found was that if I had two instances of the same templated control, say one names 'ctrl1' and the other named 'ctrl2' the timer would just keep updating one or the other like this...

page loads

--ctrl 1 loaded after delayed

--ctrl2 loaded after delayed (ctrl1's content hidden)

--ctrl1 loaded after delayed (ctrl2's content hidden)

--and so on

Very strange.


Delayed content loading is BRILLIANT!....IF you arent delaying an async callback such as a databind. What if you would like to load the graphical content FIRST and then populate a combobox with its records as the delayed content - The browser freezes until the databind is complete! Thats fine if your only VIEWING the page but what if the user would like to start entering input whilst waiting for a Suburb Dropdown to populate....


Hi Delorenzo,

Im also trying for the same. Im trying to delay content loading using ajax controls in Custom control. I have no Idea how to do it, if u got the solution for this problem then plz let me knw.

Thanks in Advance,

Rajak Shaik.


I couldn't get this to work exactly as I wanted it to, so I scrapped it and switched to a solution using JavaScript and Web Services with Prototype and Scriptaculous (for my animation). The solution works great!



Hi Delorenzo,

Thanks for replying. Can u plz tell me how it can be done using Javascript and Webservices, if possible with code.

Thanks in Advance,

Thanks & Regards,

Rajak Shaik.


Another question:

Can I do something like this below? I'd like to update the time as a process is running. However, the time on the edit box only changes (or updates) on the last one. I've tried UpdatePanel1.Update() as well and this doesn't seem to get the refresh to happen either.

protected void Timer1_Tick(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
System.Threading.Thread.Sleep(3000);
TextBox1.Text = DateTime.Now.ToString();
Timer1.Enabled = false;
}

Thanks,

Gary


Hi Gary...

I am a little unclear on what you are trying to achieve. Did you want to show the amount of time that a process takes to complete? or would you just like to show the current time and refresh it every 3 seconds?

Perhaps set the timer to 3000 and then:

protected void Timer1_Tick(object sender, EventArgs e)
{
TextBox1.Text = DateTime.Now.ToString();

Updatepanel.update

}

------
Codey


Well- not exactly so let me ask my real question. Smile I hate to get a little off the posting subject, but hopefully it's helpful.

Inside the timer I'd like to run a loop and when each loop is done then I'd like to update the date in the text box. Actually I don't really want to use a timer either, but if I can make it work that way that would be ok too. It only seems to update the text box at the end and doesn't want to update it after each loop.

protected void Timer1_Tick(object sender, EventArgs e)
{

for (int i = 0; i < 10; i++)

{

CallProcess(i);

TextBox1.Text =DateTime.Now.ToString();

UpdatePanel1.Update();

}

Thanks!!

Gary


The Update wont occur until the postback is complete, therefore the final value that you assign the textbox will be the value that is displayed.

Even though you are forcing an update on the updatepanel, that update wont display until the page completes its postback.

I see that you are trying to place a time stamp in a textbox evertime the CallProcess routine completes.

You probably need to consider multiple textboxes and a Select Case statement:

For i = 1To 10

CallProcedureHere(i)

SelectCase i

Case 1
Textbox1.text = Now
Case 2
textbox2.text = Now

EndSelect

Next

Delay content loading using ajax in Custom control?

Hi All

I Want to Delay content loading using ajax if the running controls are taking so much time in Custom control. I did this in WebPage but i have no idea about how it should be done in an Custom control. The data in custom control is coming from webservice which is taking long time, in the mean while i want to display an image saying "loading..." for it using ajax. Can anyone plz help me out.

Thanks in Advance,

Thanks & Regards,

Rajak Shaik.

Hi

I assume that you are not familiar with the AJAX UpdateProgress control.

Please find this link to see a demo and sample code. You can do it exactly what you wanted to do with this.

http://www.asp.net/AJAX/Documentation/Live/tutorials/UpdateProgressTutorials.aspx


hello.

well, that won't help him.

even though i don't agree there are some guys that are doing something like this:

1. wrap the part that has the user control with an updatepanel

2. don't make the call for loading the data when the user controlo is loaded for the 1st time

3. when the page loads on the client, they refresh the updatepanel (if you have an updateprogress, it'll kick in automatically in this case)

4. during a partial postback, you can perform the call

notice that I'm against this approach, since i believe that ajax programming should envolve mainly client side programming...


Hi,

This question has been discussed athttp://www.codeproject.com/Ajax/DelayedContentLoading.asp &http://forums.asp.net/t/1127147.aspx

Please check out these links to get some idea,

Best Regards,


Hi All,

Thanking u all for replying. I able to do this using UpdateProgress, and Script. Actually my requirement was little bit changed, i.e. i was asked to Delay content loading in case of UserControl, which is having Custom controls init. Whenever an event of Usercontrol fired then i need to display this image 'loading..." until the data comes. So i have written the code below on the webpage(which is having this Usercontrol in it).

<asp:UpdatePanelID="UpdatePanel1"runat="server">

<ContentTemplate>

<uc1:PropertiesID="usrDestination"runat="server"PageUri=""ParentUri=""/>

</ContentTemplate>

</asp:UpdatePanel>

<asp:UpdateProgressID="UpdateProgress1"AssociatedUpdatePanelID="UpdatePanel1"runat="server">

<ProgressTemplate>

<asp:imagerunat="server"ID="image2"ImageAlign="middle"ImageUrl="spinner.gif"/>

<asp:Labelrunat="Server"ID="label2"Font-Size="smaller"ForeColor="orange"Text="Loading..."/>

</ProgressTemplate>

//Script in the Body

<scripttype="text/javascript">

Sys.Application.add_load(ApplicationLoadHandler);

function ApplicationLoadHandler(sender, args)

{

var prm = Sys.WebForms.PageRequestManager.getInstance();

prm.add_initializeRequest(initRequest);

prm.add_endRequest(endRequest);

}

function initRequest(sender, args)

{

$get('UpdateProgress1').style.display ='block';

}

function endRequest(sender, args)

{

$get('UpdateProgress1').style.display ='none';

}

</script>

This is Working fine for me. I would be happy if this code helps to anyone that is in need. Thank u once again for u all for helping me in finding out the solution for this problem.

Thanks & Regards,

Rajak Shaik.

Define a PageMethod in a MasterPage

I have a web site that uses Master/Content pages and I have a PageMethod that I would like to make available to a any of the content pages. So I defined the method like I would in a Content Page:

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Text;

using System.Web;

using System.Web.Security;

using System.Web.Services;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.Web.Configuration;

publicpartialclassMasterPage : System.Web.UI.MasterPage

{

[WebMethod]

publicstaticstring MyMethod()

{

//Some Code Here

}

}

And I already have my script manager setup on the master page as follows, which works for all my PageMethod calls from Content Pages:

<asp:ScriptManagerID="masterPageScriptManager"runat="server"EnablePageMethods="true"EnablePartialRendering="true">

</asp:ScriptManager>

However, when I try to call PageMethods.MyMethod(MyMethodCompleteHandler); I get our favorite error, "PageMethods is Undefined." Is it possible to define a PageMethod in a MasterPage like this. If so what am I missing?

Thanks

Patrick

To be able to invoke that MyMethod

you need first to cast the MasterPage property of a page to your class (MasterPage) and then invoke it.

So if it was in the code behind of a content page to be able to invoke it you should write sth like :

string result = ((MasterPage)this.MasterPage).MyMethod();



Yani, I think he's talking about fromt eh javascript side.

On an unrelated note, mnogo mi obicham Bulgaria! Moja jena e bulgarka i nia otidame tam v sofia za 2-3 cedmitsi prez ljatoto vseki godina.

Paul (my apologies for grammar and spelling)


Hi Paul,

you are right about the javascript.

However, my point was that defined on the master page this static method does not become a page (content page) method. The master page is not a base class for the content pages, moreover it is a static page.

For this case it would be more suitable to create a web service, that will be accessible from everywhere.

Cheers,

Yani

PS: Paul, it is very nice you have learn some Bulgarian :)) Congrats!Wink


To answer the original question, I looked at the response in Fiddler and it looks like the Master page pagemethod doesn't get generated. I'm not yet sure how to work around that, I'll give it some thought.

Patrick,

I believe you won't be able to accomplish what you're trying with PageMethods.

The EnablePageMethods will assume that the method is defined in a.aspx page. This is why it is called a "Page Method".

If you want the method be available to all pages, why not use a simple webservice?

Default atlas:UpdatePanel Default Behavior

I feel that the default behavior for an update panel should include disabling the content/controls it contains while an update is occuring (Make all the anchors turn into divs, disable all form inputs, etc.. etc..), or at least an option for toggling that functionality. Then the atlas:UpdateProgress could contain a cancel button that would re-enable the update panel's content. It seems to me that most people would expect that behavior and it would really help developers AJAX code be a little tighter.

hello.

hum...i think that you can do that by injecting javascript on the page during the events generated by the pagerequestmanager client class...another option would be to build an extender ;)


Well, I'm sure there are plenty of ways to do it; however, what I'm trying to say is it would be nice if either (A) it was the default behavior of an atlas:updatepanel while it is updating or (B) there was a property that could easily be set to accomplish this disableDuringUpdate="true" or something like that.

My reasoning is simply that I believe many people will end up writing that code themselves while one of the main goals of .NET seems to be to write less code and make it easier for a developer to produce results faster. I don't think it would be very difficult to include with the AJAX/Atlas extensions.