How to run JavaScript prior to System.Web.UI.Timer OnTick

2009 January 21

The short answer: you can’t … or at least not easily, but there is a better way.

Let’s say you have a page that needs to post back every x minutes. In my case, I needed to implement an auto-save feature that the client requested. Saving the data would happen server side so I just used a Timer to initiate regular post backs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%@ Page Language="C#" %>
<script runat="server">
    protected void Timer1_OnTick(object sender, EventArgs e)
    {
        Response.Write("Last Postback: " + DateTime.Now.ToString());
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="sm" runat="server" />
        <asp:Timer ID="Timer1" runat="server" 
                OnTick="Timer1_OnTick" Interval="4000" />
    </form>
</body>
</html>

The problem surfaced when they also wanted a client-side prompt to allow or cancel the auto post back. System.Web.UI.Timer does not have any client side events exposed, so I searched the web and asked our friends over at StackOverflow what they would do.

The only response to my post confirmed that the Timer is a bad fit for this situation. I could hack it, but there must be a better way.

Square Peg in a Round Hole

Square Peg in a Round Hole

Instead of using a Timer to initiate post backs, I switched to a combination of setTimeout() and __doPostBack(). It’s pure html and JavaScript goodness!

In this example, I added an update panel to demonstrate how __doPostBack() can also be used to create a partial post back (leaving some parts of the page unchanged after the auto post back). That is not necessary, but if you are posting back to the server automatically, an AJAX experience will probably be better for the user.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<%@ Page Language="C#" %>
<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack)
        {
            string time = DateTime.Now.ToString();
            this.insidePanelLabel.Text = "Last Postback: " + time;
            this.outsidePanelLabel.Text = "blah blah"; // Does not show up after partial post back.
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
    <script type="text/javascript" language="javascript">
        window.onload = function() {
            // start the auto postback timer.
            setPostbackTimer(8);
        }
        function setPostbackTimer(seconds) {
            window.setTimeout("conditionalPostback()", seconds * 1000);
        }
        function canContinue() {
            return confirm('The page is requesting new data.  Ok or Cancel?');
        }
        function conditionalPostback() {
            if (canContinue()) {
                // User permits the postback. 
                // Do it.
                __doPostBack('UpdatePanel1', '');
            }
            else {
                // User denied the postback. 
                // Reset the timer (they will be prompted again).
                setPostbackTimer(8);
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="sm" runat="server" />
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Label ID="insidePanelLabel" runat="server" 
                    Text="This text will change during auto postbacks."/>
            </ContentTemplate>
        </asp:UpdatePanel>
        <br />
        <asp:Label ID="outsidePanelLabel" runat="server" 
            Text="This text will not change during auto postbacks."/>
    </form>
</body>
</html>

Have you ever tried to make Microsoft controls fit into a situation only to find that plain html and JavaScript are a better fit?

The WebForms model often leads me to over rely on controls and I forget that plain html and JavaScript solutions are available too. Using controls is fine, but think twice if you have to hack them to get what you want. There is probably a better way.

Happy coding.

2 Responses leave one →
  1. 2009 December 4
    Kipetcoff permalink

    Thanks, it was useful.

  2. 2010 November 22
    tanya permalink

    Hi….. m having same problem.. i want some javascript to run at ontick event…. i tried this code instead.. it works fine with thast script…. but we can clearly figure out refreshments for this….. which is not problem with timer control…….plz help

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS

This work by Robert Claypool is licensed under a Creative Commons Attribution 3.0 United States.