SharePoint 2007 AJAX Timer Fires Only Once?

Please use the page tabs to navigate through the article.

I have been recently creating a solution for SharePoint 2007 which had a number of pre-requisites to be confirmed prior to allowing the user to perform their action – a pre-flight check if you will. I wanted to provide a visual indication that these checks were being performed and their success / failure so decided on a AJAX timer.

An AJAX timer allows you to do Postbacks at a set interval and when combined with an UpdatePanel allow you to update a section of, or entire page. The control is something like;

<asp:Timer runat="server" ID="UpdateTimer" Interval="1000" OnTick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" ID="TimedPanel" UpdateMode="Conditional">
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="UpdateTimer" EventName="Tick" />
    </Triggers>
    <ContentTemplate>

        <asp:Panel ID="Panel1" runat="server" Visible="true">
            <asp:Image ID="ProgressGIF" runat="server" ImageUrl="Progress.gif" />
        </asp:Panel>

        <asp:Panel ID="Panel2" runat="server" Visible="false">
        </asp:Panel>

        <asp:Panel ID="Panel3" runat="server" Visible="false">
        </asp:Panel>

    </ContentTemplate>
</asp:UpdatePanel>

with the code behind being;

protected void UpdateTimer_Tick(object sender, EventArgs e)
{
    if(ConditionA == true)
        Panel2.Visible = true;

    if(ConditionB == true)
        Panel3.Visible = true;

    if (ConditionA == true && ConditionB == true)
    {
        Panel1.Visible = false;
        UpdateTimer.Enabled = false;
    }
}

With this combination the UpdateTimer_Tick method will be run every 1000ms (1 second) and if certain conditions are met various panels will be shown in the UpdatePanel.

Note: its always best to have a

UpdateTime.Enable = false

in your code else it will run forever. You should also have a timeout condition in place as well.

When I punched the solution into SharePoint 2007 I found that the UpdateTimer_Tick method would only run once. I must admit I spent some time on it, rebuilding, tweaking, debugging – I even built the solution in a new stock ASP site – everything looked ok but in SharePoint 2007 it still only run once.

After some research on I found references to the issue being the _spFormOnSubmitWrapper method on the SharePoint init.js file. The most widely referenced explanation of the issue can be found under “3.6 What’s this bug!” in this post at http://www.bewise.fr. The post goes on to recommend a fix which involves editing the init.js file.

I dont like editing the out-of-the-box files in SharePoint, so I continued my research into ways the method could be overridden locally. The collection of this research is the below javascript file;

<script type="text/javascript">
function _spFormOnSubmitWrapper()
{
    /*
    The native init.js sharepoint script does not handle ajax timers.
    The timer tasks only runs once. The inclusion of this script
    overrides the native method to correct the issue.
    */

    if (_spSuppressFormOnSubmitWrapper)
    {
        return true;
    }
 
    if (_spFormOnSubmitCalled)
    {
        //----------------------
        //this section of code added to fix postback
        //issues with AJAX controls.
        if ((typeof (Sys) != 'undefined')
            && (typeof (Sys.WebForms) != 'undefined')
            && (Sys.WebForms.PageRequestManager.getInstance() != null)
            && (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.panelID != ''))
                _spFormOnSubmitCalled = false;
        else _spFormOnSubmitCalled = true;
        //----------------------
    }

    if (typeof (_spFormOnSubmit) == "function")
    {
        var retval = _spFormOnSubmit();
        var testval = false;

        if (typeof (retval) == typeof (testval) && retval == testval)
        {
            return false;
        }
    }

    if ((typeof (Sys) != 'undefined')
        && (typeof (Sys.WebForms) != 'undefined')
        && (Sys.WebForms.PageRequestManager.getInstance() != null)
        && (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.panelID != ''))
            _spFormOnSubmitCalled = false;
    else _spFormOnSubmitCalled = true;

    RestoreToOriginalFormAction();

    _spFormOnSubmitCalled = true;

    return true;
}
</script>

Placing this script into the top of your user control overrides the out-of-the-box method and corrects the reaction to the UpdateTimer after the first “tick”, making the control run just as expected.

For a full example of the code return to the top and select the “Full Example Code” tab…

<script type="text/javascript">

function _spFormOnSubmitWrapper()
{
    /*
    The native init.js sharepoint script does not handle ajax timers.
    The timer tasks only runs once. The inclusion of this script
    overrides the native method to correct the issue.
    */

    if (_spSuppressFormOnSubmitWrapper)
    {
        return true;
    }
 
    if (_spFormOnSubmitCalled)
    {
        //----------------------
        //this section of code added to fix postback
        //issues with AJAX controls.
        if ((typeof (Sys) != 'undefined')
            && (typeof (Sys.WebForms) != 'undefined')
            && (Sys.WebForms.PageRequestManager.getInstance() != null)
            && (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.panelID != ''))
                _spFormOnSubmitCalled = false;
        else _spFormOnSubmitCalled = true;
        //----------------------
    }

    if (typeof (_spFormOnSubmit) == "function")
    {
        var retval = _spFormOnSubmit();
        var testval = false;

        if (typeof (retval) == typeof (testval) && retval == testval)
        {
            return false;
        }
    }

    if ((typeof (Sys) != 'undefined')
        && (typeof (Sys.WebForms) != 'undefined')
        && (Sys.WebForms.PageRequestManager.getInstance() != null)
        && (Sys.WebForms.PageRequestManager.getInstance()._postBackSettings.panelID != ''))
            _spFormOnSubmitCalled = false;
    else _spFormOnSubmitCalled = true;

    RestoreToOriginalFormAction();

    _spFormOnSubmitCalled = true;

    return true;
}
</script>

<asp:Timer runat="server" ID="UpdateTimer" Interval="1000" OnTick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" ID="TimedPanel" UpdateMode="Conditional">
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="UpdateTimer" EventName="Tick" />
    </Triggers>
    <ContentTemplate>

        <asp:Panel ID="Panel1" runat="server" Visible="true">
            <asp:Image ID="ProgressGIF" runat="server" ImageUrl="Progress.gif" />
        </asp:Panel>

        <asp:Panel ID="Panel2" runat="server" Visible="false">
        </asp:Panel>

        <asp:Panel ID="Panel3" runat="server" Visible="false">
        </asp:Panel>

    </ContentTemplate>
</asp:UpdatePanel>

Return to top of article to go to next page…

Related:

4 Comments


  1. Rajesh Singh
    Jan 05, 2012

    This is best one article so far I have read online. I would like to appreciate you for making it very simple and easy. I have found another nice post related to this post over the internet which also explained very well. For more details you may check it by visiting this url……..

    http://mindstick.com/Articles/385ebacd-89e2-40d3-868a-0185e7c45f15/?ASP.Net%20AJAX%20Server%20Control:%20Timer

    Thanks


  2. aaron
    Jan 08, 2012

    Glad it helped Rajesh.


  3. David
    Feb 01, 2012

    You, sir, have just earned yourself a cookie. Thank you. This helped us solve a bug we’ve been at for days. Thank you.


  4. aaron
    Feb 01, 2012

    Glad it helped David, It had me stuck for a bit too!

Leave a Reply


Latest Videos