I have a page with some UpdatePanels, each one with its own button to update it. Since the update routines can take some time, I thought making them Asynchronous would help loading the page step by step.
But doing so, when I fire programatically the update routine of each panel, I get only the last UpdatePanel updated.
Here is an example of the code, with two UpdatePanels. There is the requirement that the update routine have to be fired on clientside pageLoad function.
Is it a bug or am I missing something in the code?
Thanks =)
<asp:UpdatePanel ID="Panel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="Text1" runat="server" />
<asp:Button ID="Button1" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:UpdatePanel ID="Panel2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="Text2" runat="server" />
<asp:Button ID="Button2" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
And the client-side code:
function pageLoad()
{
$('#Button1').click();
$('#Button2').click();
}
Here is why:
By default, when a page makes multiple
asynchronous postbacks at the same
time, the postback made most recently
takes precedence.
http://www.asp.net/ajax/documentation/live/tutorials/ExclusiveAsyncPostback.aspx
Here is a solution:
Handling Multiple Asynchronous Postbacks
Related
Consider the following code fragment:
<div>
<asp:Button runat="server" ID="trickyUPTrigger" Text="Tricky Update" />
<div>
<asp:Button runat="server" ID="normalUPTrigger" OnClick="normalUPTrigger_Click" Text="Normal Update" />
<asp:UpdatePanel runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="normalUPTrigger" />
</Triggers>
<ContentTemplate>
<asp:Label runat="server" ID="changeableLabel" Text="Change me"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
Now make the button with ID of trickyUPTrigger as the trigger of the UpdatePanel. Or, devise a mechanism (probably... using javascript?) so that when this button is clicked UpdatePanel updates without full page postback.
If you want to update the UpdatePanel when clicking on trickyUPTrigger, you can add that button to the triggers list:
<asp:UpdatePanel runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="normalUPTrigger" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="trickyUPTrigger" EventName="Click" />
</Triggers>
<ContentTemplate>
...
</ContentTemplate>
</asp:UpdatePanel>
UPDATE
You asked some code examples showing cases with naming containers, a concept that comes into play for databound controls with item templates, like the GridView and the ListView, and for user controls. In the examples below, I use a ListView, where each item is a separate naming container.
If you wanted to trigger an update of your panel from a button in a ListView item template, the trigger would not be found at runtime, and an exception would occur:
<asp:ListView ID="lstView" runat="server">
<ItemTemplate>
<asp:Button ID="anotherTrigger" runat="server" Text="This trigger cannot be found!" OnClick="anotherTrigger_Click" />
</ItemTemplate>
</asp:ListView>
<asp:UpdatePanel runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="anotherTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
The reverse case (the UpdatePanel in the ListView item template, the trigger button outside of the ListView) does work, according to my tests, which seems to contradict the note that you mention in your comment:
<asp:ListView ID="lstView" runat="server">
<ItemTemplate>
<asp:UpdatePanel runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="anotherTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</ItemTemplate>
</asp:ListView>
<asp:Button ID="anotherTrigger" runat="server" Text="This trigger works!" OnClick="anotherTrigger_Click" />
Finally, the case where the UpdatePanel and the trigger button are both in the ListView item template also works:
<asp:ListView ID="lstView" runat="server">
<ItemTemplate>
<asp:Button ID="anotherTrigger" runat="server" Text="This trigger works!" OnClick="anotherTrigger_Click" />
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="anotherTrigger" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</ItemTemplate>
</asp:ListView>
You can notice that I set UpdateMode="Conditional" for the panel in this last example. With this setting, the panel is updated only by its own triggers. If the attribute is set to UpdateMode="Always", the panel is updated not only by his own triggers but also by the triggers of the other UpdatePanels in the page. The default value is UpdateMode="Always" (as in your code sample).
I have the following updatepanel in the masterpage:
<asp:UpdatePanel runat="server" id="pnlHeartBeat" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="HeartBeat" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Timer runat="server" id="HeartBeat" Interval="180000" OnTick="Heartbeat_OnTick"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
This runs fine no matter where I am in the site... right up to the point I navigate to a content page with another updatepanel, after which whenever the masterpage's updatepanel is triggered, so will the content page's updatepanel.
Here's a content page updatepanel:
<asp:UpdatePanel ID="ajaxColumnGroups" runat="server" ChildrenAsTriggers="true" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="cboxAllorNone" EventName="CheckedChanged" />
</Triggers>
<contenttemplate>
<dx:ASPxCheckBox ID="cboxAllorNone" runat="server" text="Select/Deselect All" OnCheckedChanged="cboxAllorNone_CheckChanged" autopostback="true"></dx:ASPxCheckBox>
<dx:ASPxPageControl runat="server" id="tabColumnGroups" ActiveTabIndex="0"></dx:ASPxPageControl>
</contenttemplate>
</asp:UpdatePanel>
How can I stop this behavior?
Thanks
I've added a CalendarExtender to reset the dates of a datasource for a grid view.
Code -
<asp:UpdatePanel ID="UPTabs" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="tbMoveInDate" eventname="TextChanged" />
</Triggers>
<ContentTemplate>
<asp:TextBox ID="tbMoveInDate" Width="70px" AutoPostBack="true" runat="server"/>
<asp:CalendarExtender ID="tbMoveInDateCalendarExtender" runat="server" Format="MM/yyyy"
TargetControlID="tbMoveInDate" OnClientHidden="onCalendarHidden" OnClientShown="onCalendarShown" />
<asp:GridView ID="gvMoveins" runat="server" .../>
</ContentTemplate>
</asp:UpdatePanel>
with the intention of forcing the update panel to update when the date is changed.
What am I missing?
Need to use
<asp:PostBackTrigger />
to get the effect I needed.
I have a page and it has a button and a user control.
I want to refresh the user control without refreshing the page.
I know I cannot do it otherwise so what I did is wrapped my user control inside the Update Panel.
<asp:TextBox ID="txtName" runat="server"></asp:TextBox><br />
<asp:Button ID="btnAdd" runat="server" Text="Add name to list" OnClick="btnAdd_Click" /><br /><br />
<asp:UpdatePanel ID="upShowNames" runat="server">
<ContentTemplate>
<uc1:ShowNames ID="ucShowNames" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAdd" />
</Triggers>
</asp:UpdatePanel>
But I still the control won't refresh.
I also tried calling the update panels. The Update() method by changing its UpdateMode to Conditional but that does not work either...
Does anyone know how can I do it?
Please change these 2 things
<asp:UpdatePanel ID="upShowNames" runat="server" UpdateMode="Conditional">
<asp:AsyncPostBackTrigger ControlID="btnAdd" EventName="Click"/>
You missed the EventName on the postback trigger, once you add that, it should work :-)
My team and I are working on a portal applicaiton. When a user requests a page, we get a page object (contianing permissions, actual file to use and what not). We then do a Response.Redirect to "~/Default.aspx".
The crazy thing is that when the code to validate access and what not is called from a button click event from within an ajax update panel, response.redirect is pasting a "&f2" or a "/" into the url. So rather than http://localhost/Default.aspx, the webbrowser is being redirected to http://localhost/%f2Default.aspx, and is subsequently returning a 404 error.
HttpContext.Current.Response.Redirect("~/Default.aspx", false);
Anyone have an idea of why this would occur? And it only happens when the click event fires inside an update panel.
It sounds like it is escaping the URL. Can you call a method on the code that is generating the URL to decode it before output?
The solution is to set up the update panel like this:
<asp:UpdatePanel ChildrenAsTriggers="false" UpdateMode="Conditional" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlNewAddressCountry" EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger ControlID="ddlAddressState" EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger ControlID="ddlNewAddressCity" EventName="SelectedIndexChanged" />
<asp:AsyncPostBackTrigger ControlID="ddlNewAddressPostalCode" EventName="SelectedIndexChanged" />
<asp:PostBackTrigger ControlID="btnCustomerAddressEditCancel" />
</Triggers>
...
<td colspan="2">
<asp:Button ID="btnCustomerAddressEditSave" runat="server" OnClick="CustomerAddressEditSave_Click"
Text="Save" />
<asp:Button ID="btnCustomerAddressEditCancel" runat="server" CausesValidation="false" OnClick="CustomerAddressEditCancel_Click"
Text="Cancel" />
<asp:Button ID="btnCustomerAddressEditDelete" runat="server" OnClick="CustomerAddressEditDelete_Click" OnClientClick="return confirm('Are you sure you want to delete this record?');"
Text="Delete" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>