views:

284

answers:

3

Hi I need to intercept server callback after udate panel async post back and determine which panel initiated the request. The code is pretty simple:

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(InterceptUpdateCallback);

function InterceptUpdateCallback(sender, args)
{
    var updatedPanels = args.get_panelsUpdated();    
    for (idx = 0; idx < updatedPanels.length; idx++) {
        if (updatedPanels[idx].id == "myUpdatePanel") {            
            StartSmth();
            break;
        }
      }
}

And it works when UpdatePanel is not inside another UpdatePanel. But when it is inside another UpdatePanel updatedPanels[idx].id has parent Updatepanel id. So how can I get the id of UpdatePanel which initiated the request (the inner UpdatePanel)? Thanx

A: 

I will have a guess at this one.

Does setting UpdateMode = Conditional on the outer (or both) UpdatePanels help? I think the problem is that you only get the "outermost" updated panel and if you do not set UpdateMode to Conditional the outer Panel is updated as well (even if you click something in the inner panel; see second reference).

For reference see

Note that, if I remove the property UpdateMode=Conditional for the UpdatePanel1 (parent), both the labels will get refreshed.

from ASP.NET 2.0 AJAX Extensions Update Panel - Nested Update Panel

and

When set to Always, the UpdatePanel is updated on every postback raised from anywhere in the page, so from controls inside the panel, inside other panels or just on the page.

from Remember to set UpdatePanel's UpdateMode to Conditional

scherand
+2  A: 

Here you go:

function InterceptUpdateCallback(sender, args) {
 if (sender._postBackSettings)
    alert(sender._postBackSettings.panelID);
 else
    alert('first load');    
}

Update:

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
<script runat="server">
    protected void LinkButtons_Click(object sender, EventArgs e)
    {
        LabelMain.Text = LabelSub1.Text = LabelSub2.Text = LabelSub3.Text = string.Format("{0} Updated By {1}", DateTime.Now, ((Control)sender).ID);
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head runat="server">
    <style type="text/css">
        body { font-family: Tahoma;}
        fieldset { padding: 15px; }
        fieldset a 
        {
            float: right;
            clear: none;
            display: block;
            margin: 10px;
        }
        fieldset span
        {
            display: block;
            margin-top: 20px;
            margin-bottom: 20px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <script type="text/javascript">
        function pageLoaded(sender, args) {
            if (sender._postBackSettings) {
                var panelId = sender._postBackSettings.panelID.split('|')[0];
                if (panelId == sender._scriptManagerID) {
                    var updatedPanels = args.get_panelsUpdated();
                    var affectedPanels = "Affected Panels:\n";
                    for(var x=0;x<updatedPanels.length;x++)
                        affectedPanels+= updatedPanels[x].id + "\n";
                    alert("Request initiated by ScriptManager\n\nMight be an async trigger, or child of an update panel with children as triggers set to false.\n\n"+affectedPanels);
                }
                else
                    alert("Request initiated by: " + panelId);
            }
        }
        Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);
    </script>

    <asp:LinkButton ID="UpdateMain" runat="server" Text="UpdateMain" OnClick="LinkButtons_Click"></asp:LinkButton>,
    <asp:LinkButton ID="UpdateSub1" runat="server" Text="UpdateSub1" OnClick="LinkButtons_Click"></asp:LinkButton>,
    <asp:LinkButton ID="UpdateSub2" runat="server" Text="UpdateSub2" OnClick="LinkButtons_Click"></asp:LinkButton>,
    <asp:LinkButton ID="UpdateSub3" runat="server" Text="UpdateSub3" OnClick="LinkButtons_Click"></asp:LinkButton>
    <br />
    <br />
    <asp:UpdatePanel ID="Main" runat="server" ChildrenAsTriggers="false" UpdateMode="Conditional">
        <ContentTemplate>
            <fieldset>
                <asp:LinkButton ID="LinkButton1" runat="server" Text="LinkButton1" OnClick="LinkButtons_Click"></asp:LinkButton>
                <legend>Main -  Update Mode:Conditional, Children As Triggers:False</legend>
                <asp:Label ID="LabelMain" runat="server" Text="LabelMain"></asp:Label>
                <asp:UpdatePanel ID="Sub1" runat="server" UpdateMode="Always" ChildrenAsTriggers="true">
                    <ContentTemplate>
                        <fieldset>
                            <asp:LinkButton ID="LinkButton2" runat="server" Text="LinkButton2" OnClick="LinkButtons_Click"></asp:LinkButton>
                            <legend>Sub1 - Update Mode:Always, Children As Triggers:True</legend>
                            <asp:Label ID="LabelSub1" runat="server" Text="LabelSub1"></asp:Label>
                            <asp:UpdatePanel ID="Sub2" runat="server"  UpdateMode="Always" ChildrenAsTriggers="true">
                                <ContentTemplate>
                                    <fieldset>
                                        <asp:LinkButton ID="LinkButton3" runat="server" Text="LinkButton3" OnClick="LinkButtons_Click"></asp:LinkButton>
                                        <legend>Sub2 - Update Mode:Always, Children As Triggers:True</legend>
                                        <asp:Label ID="LabelSub2" runat="server" Text="LabelSub2"></asp:Label>
                                    </fieldset>
                                </ContentTemplate>
                                <Triggers>
                                    <asp:AsyncPostBackTrigger ControlID="UpdateSub2" />
                                </Triggers>
                            </asp:UpdatePanel>                            
                        </fieldset>                        
                    </ContentTemplate>
                    <Triggers>
                        <asp:AsyncPostBackTrigger ControlID="UpdateSub1" />
                    </Triggers>
                </asp:UpdatePanel>
                <asp:UpdatePanel ID="Sub3" runat="server" ChildrenAsTriggers="false" UpdateMode="Conditional">
                    <ContentTemplate>

                        <fieldset>
                            <asp:LinkButton ID="LinkButton4" runat="server" Text="LinkButton4" OnClick="LinkButtons_Click"></asp:LinkButton>
                            <legend>Sub3 - Update Mode:Conditional, Children As Triggers:False</legend>
                            <asp:Label ID="LabelSub3" runat="server" Text="LabelSub3"></asp:Label>
                        </fieldset>                        
                    </ContentTemplate>
                    <Triggers>
                        <asp:AsyncPostBackTrigger ControlID="UpdateSub3" />
                    </Triggers>
                </asp:UpdatePanel>
            </fieldset>
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="UpdateMain" />
        </Triggers>
    </asp:UpdatePanel>
    </form>
</body>
</html>
MK
I doubt it will work since _postBackSettings is an internal property so you can't call it from your code directly.
Voice
this is javascript !! and it will give you the update panel id and the firing element id like this "UpdatePanel1|Button1".Did you try it ?!
MK
Yes I tried and error occurs since sender._postBackSettings is not avaliable
Voice
This is why I put a condition, when sender._postBackSettings == null it means the page was loaded (no postback, i.e: "first load"). It is filled when an update panel initiates a request.
MK
I updated my answer with an illustration page, check it.
MK
A: 

Finally I came to solution: the problem was that I had trigger control (Button) for child UpdatePanel which actually was outside this Update panel and inside parent UpdatePanel (sorry I hadn't noticed that). If you put Button inside child UpdatePanel - everything works fine.

Voice