views:

248

answers:

2

Hi

The javascript generated by the asp.net SciptManager control seems to have a bug and cant handle hidden UpdatePanels. A javascript error is thrown when a control within one updated panel tries to make another update panel visible. Is this a bug with ASP.Net ajax? And does anyone have any ideas how to get around this?

heres is an example of what im trying to do

<script type="text/C#" runat="server">
    protected void LinkButton1_Click(object sender, EventArgs e)
    {
        Panel1.Visible = true;
    }
</script>

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
        <asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click" Text="Show Panel"></asp:LinkButton>
    </ContentTemplate>
</asp:UpdatePanel>

<asp:Panel ID="Panel1" runat="server" Visible="false">
    <asp:UpdatePanel ID="UpdatePanel2" runat="server">
        <ContentTemplate>
            blah bla blah
        </ContentTemplate>
    </asp:UpdatePanel>
</asp:Panel>

this is the javascript error that gets thrown when clicking on the "LinkButton1" link. This error comes from the javascript that is generated by the asp.net ScriptManager control

Error: Sys.InvalidOperationException: Could not find UpdatePanel with ID 'ctl00_ContentPlaceHolder1_UpdatePanel2'
+1  A: 

The error you get is not from the Javacript, but from asp.net.

You get it because you try to make visible the Panel1, that is outside the UpdatePanel that you call it, and this is not possible.

Everything that you going to update on the web page must be inside the UpdatePanel that you call.

Aristos
+1  A: 

You're running into problems because Panel1's contents are not rendered when the page is first rendered. This has the effect that UpdatePanel2 is not properly initialised.

(The page request manager, which manages all the partial updates, needs to be aware of UpdatePanel2's existence and this just won't happen if it is not rendered. Also, if you think about it, the update panel needs to render some elements if only to add a placeholder div into which it will inject its content on partial postbacks).

I don't know precisely what you are trying to achieve but, if you simply want your UpdatePanel2 to be triggered by a control that is not itself inside the update panel, then set LinkButton1 as a trigger like so.

<script runat="server">
    protected void LinkButton1_Click(object sender, EventArgs e)
    {
        blabla.Visible = true;
    }
</script>

<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">
</asp:ScriptManager>

<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click" Text="Show Panel"></asp:LinkButton>

<asp:UpdatePanel ID="UpdatePanel2" runat="server" >
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="LinkButton1" />
    </Triggers>
    <ContentTemplate>
        <asp:PlaceHolder runat="server" ID="blabla" Visible="false">
        blah bla blah
        </asp:PlaceHolder>
    </ContentTemplate>
</asp:UpdatePanel>

If LinkButton1 must indeed be inside an update panel (perhaps LinkButton1 is not always visible?) then you can do something like the following

<script runat="server">
    protected void LinkButton1_Click(object sender, EventArgs e)
    {
        blabla.Visible = true;
        UpdatePanel2.Update();
    }
</script>

<asp:ScriptManager ID="ScriptManager1" runat="server" ScriptMode="Debug">
</asp:ScriptManager>

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" >
    <ContentTemplate>
        <asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click" Text="Show Panel"></asp:LinkButton>
    </ContentTemplate>
</asp:UpdatePanel>

<asp:UpdatePanel ID="UpdatePanel2" runat="server" UpdateMode="Conditional" >
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="LinkButton1" />
    </Triggers>
    <ContentTemplate>
        <asp:PlaceHolder runat="server" ID="blabla" Visible="false">
        blah bla blah
        </asp:PlaceHolder>
    </ContentTemplate>
</asp:UpdatePanel>
Chris F
thanks for thorough response.you would think the page request manager would be smart enough to realise the second updatepanel isnt rendered on the page. your second suggestion is close to what im trying to do. but doing it that way would mean that the update panel would have to surround all the contents of the placeholder, when, in my case, only a small part of that contents needs to use ajax.
MakkyNZ
Why not just wrap the update panel and place holder around only the content that needs to be updated then?
Chris F