I would love to add AsyncPostback Triggers dynamically to the ImageButtons found within the UpdatePanel control
<asp:Content ID="Content1" ContentPlaceHolderID="Content" runat="server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers></Triggers>
<ContentTemplate>
<asp:ListView ID="ListView2" runat="server">
<ItemTemplate>
<asp:ImageButton ID="btnRemove" runat="server" ImageUrl="~/Images/Delete.png" CommandName='<%# DataBinder.Eval(Container.DataItem, "QuestionsID") %>'/>
</ItemTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
The problem is that i cannot figure out how to do it!
I already tried different ways, but NONE seems to work.
My last try, was trying to add the triggers in the ListView ItemDataBound event
Private Sub ListView2_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ListView2.ItemDataBound
For Each btnError As ImageButton In e.Item.Controls.OfType(Of ImageButton)()
Select Case btnError.ID
Case "btnRemove"
Dim trigger As New AsyncPostBackTrigger()
trigger.ControlID = UpdatePanel1.FindControl(btnError.ID).UniqueID
UpdatePanel1.Triggers.Add(trigger)
End Select
Next
End Sub
which of course is not correct.
So could you please tell me how can i add dynamically triggers to the UpdatePanel controls?
Since your buttons are already inside the update panel there is no reason for adding them dynamically as they generate an async postback anyway.
Related
I have a simple command event that toggles the visibility of two buttons.
When the controls are wrapped in an update panel as below, each subsequent click does not toggle the visibility of the buttons even though the code executes as expected.
Testing
The code works as expected when the update panel is removed.
After clicking the button refreshing the page reflects the changes made.
The issue clearly lies with refreshing the content after a postback.
I have tried upd.update and updateMode="always"
ASPX
<asp:UpdatePanel ID="upd" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater ID="rpt" runat="Server">
<ItemTemplate>
<asp:Button ID="btnOn" runat="Server" Text="ON" CommandName="ON" CommandArgument='<%#: Container.ItemIndex%>' UseSubmitBehavior="false" />
<asp:Button ID="btnOff" runat="Server" Text="OFF" CommandName="OFF" CommandArgument='<%#: Container.ItemIndex%>' UseSubmitBehavior="false" />
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
VB.NET
Protected Sub Page_PreRenderComplete(sender As Object, e As EventArgs) Handles Me.PreRenderComplete
For Each item In rpt.Items
'Do a check and set output'
btnOn.Visible = Not Output
btnOff.Visible = Output
Next
End Sub
I have an update panel that includes a gridview.
This grid has a drop down list column.
Beta aspx code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" EnablePartialRendering="false" UpdateMode="Conditional">
...
<asp:GridView ID="Gv_Queue" runat="server">
<Columns>
<asp:TemplateField HeaderText="H">
<ItemTemplate>
<asp:DropDownList ID="ddl_proprietà" runat="server" OnSelectedIndexChanged="ddl_proprietà_SelectedIndexChanged" AutoPostBack="true"/>
</ItemTemplate>
</Columns>
</asp:GridView
</asp:UpdatePanel>
I add the triggers of the DDL in the UpdatePanel by code:
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = dl.UniqueID; //dl is the Drop Down control
UpdatePanel1.Triggers.Add(trigger);
It works good at the fist selectedIndexChanged event... but the second time that the event is fired the trigger does not work correctly because a post back operation runs.
I already tried:
to change the AsyncPostBackTrigger to a PostBackTrigger but a missing
component exception is thrown.
change the updateMode in theUpdatePanel attribute to 'Always'.
Put another UpdatePanel in the ItemTemplate Column only for the
DropDown.
You have to re-create the trigger on every postback. You could add this code to the Load event of the DropDownList:
aspx:
<asp:TemplateField HeaderText="H">
<ItemTemplate>
<asp:DropDownList ID="ddl_proprietà" OnLoad="ddl_proprietà_OnLoad" runat="server" OnSelectedIndexChanged="ddl_proprietà_SelectedIndexChanged" AutoPostBack="true"/>
</ItemTemplate>
</asp:TemplateField>
codebehind:
protected void ddl_proprietà_OnLoad(object sender, EventArgs e)
{
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = ((Control)sender).UniqueID; // sender is the DropDown control
UpdatePanel1.Triggers.Add(trigger);
}
I found a solution to my own question.
You were all rights: I naively forgot that the trigger did not work after the first event just because it must be recreate.
Strangely even the recreation of the trigger in the on_Load even did not resolve the problem.
I did the trick with another update panel like this:
<asp:TemplateField HeaderText="H">
<ItemTemplate>
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="ddl_proprietà" runat="server" OnSelectedIndexChanged="ddl_proprietà_SelectedIndexChanged"
AutoPostBack="true"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddl_proprietà" />
</Triggers>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
In my case the issue was because I had 2 controls on the page with the same Id. You may want to check this out if the previous responses did not resolve the issue.
I'm new in using UpdatePanel, I Have 2 DropDownList:
DropDownList_1 and DropDownList_2
where DropDownList_2 content will be dependent to DropDownList_1 selected value, here is my code:
ASPX:
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DropDownList_1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList_1_SelectedIndexChanged" DataSourceID="businessgroup" DataTextField="BusinessGroupName" DataValueField="Id"></asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownList_1" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
<asp:DropDownList ID="DropDownList_2" runat="server" DataSourceID="jobposition" DataTextField="JobPositionName" DataValueField="Id"></asp:DropDownList>
CS:
protected void DropDownList_1_SelectedIndexChanged(object sender, EventArgs e)
{
SqlDataSource1.SelectCommand = "SELECT DISTINCT * FROM [JobPosition] WHERE BusinessGroupID ="+DropDownList_1.SelectedValue;
DropDownList_2.DataBind();
}
its working as stated above but what I doesn't want in my output is the whole page refreshes, I also tried removing AutoPostBack="true" in my DropDownList_1 but it stops working, what am I doing wrong in here? Thanks!
EDIT:
I also tried moving the DropDownList_2 inside UpdatePanel's ContentTemplate but still the whole page is refreshing.
Here is how you should do:
If you want to refresh the second drop-down, than the second drop-down should be inside an update panel
Set AutoPostBack="true" only for the second drop-down
Set UpdateMode="Conditional" for the update panel (otherwise they will refresh every time)
Set the AsyncPostBackTrigger of the panel to point to the first drop-down SelectedIndexChanged event
Set ChildrenAsTriggers="true" for the Update panel
:
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" OnSelectedIndexChanged="DropDownList_1_SelectedIndexChanged" DataSourceID="businessgroup" DataTextField="BusinessGroupName" DataValueField="Id"></asp:DropDownList>
<asp:DropDownList ID="DropDownList_2" runat="server" AutoPostBack="true" DataSourceID="jobposition" DataTextField="JobPositionName" DataValueField="Id"></asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownList_1" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
The controls should reside in the same update panel, it's simpler this way.
I found the fix, thanks to Cristina for reminding me to check the console errors. And just for reference to anyone who is having the same problem here is what I've done:
I have missing Ajax libraries, so I imported the MicrosoftAjax.js and MicrosoftAjaxWebService in this folder Scripts>WebForms>MSAjax.
After I imported the necessary Ajax library I've got this console error:
MicrosoftAjaxWebForms.js:6 Uncaught
Sys.WebForms.PageRequestManagerServerErrorException:
Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback
or callback argument. Event validation is enabled using in configuration or <%# Page
EnableEventValidation="true" %> in a page. For security purposes,
this feature verifies that arguments to postback or callback events
originate from the server control that originally rendered them. If
the data is valid and expected, use the
ClientScriptManager.RegisterForEventValidation method in order to
register the postback or callback data for validation.
What I did is add EnableEventValidation="false" inside this Ajax page, in <%Page %> directive.
And after that I have no longer full page reload and all is working now on how I wanted.
If your panel still posts back after you've set it up as per guidelines, check that you have not set ClientIDMode="Static" either for the specific control performing the callback or by causing the ClientIDMode to default to static inherited from either in web.config, the Page or parent containers.
Search your solution for ClientIDMode="Static" and either change this for inherited controls including the one triggering the postback, or explicitly set ClientIDMode="Predictable" or ClientIDMode="AutoID" for each of your controls that trigger a postback.
While you are working with update panel you have to register your events while refreshing the page for that you have to use Microsoft's PageRequestManager
to re-subscribe every update.
You have to initialize your event in the document.ready(function(){})
of the javascript.
Ex: var test=Sys.WebForms.PageRequestManager.getInstance();
Basically I have this situation
Page >
Update Panel >
User Control >
List View >
User Control (Within item template) >
Update Panel
When I click on a button within the inner most update panel, I want the content of the update panel to update. This isn't happening. However, the click handler is being hit fine asynchronously. The update panel just doesn't want to update.
Code - I've created a simple test web app that replicates the problem, and shared it on my google drive: UpdatePanelInListViewTest.zip, but here's the markup:
Page:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="ajaxParent" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<uc1:ListUserControl ID="ListUserControl1" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
List User Control:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ListUserControl.ascx.cs" Inherits="UpdatePanelInListViewTest.ListUserControl" %>
<%# Register src="MiniWidget.ascx" tagname="MiniWidget" tagprefix="uc1" %>
<asp:ListView ID="lstTest" runat="server">
<ItemTemplate>
Item
<uc1:MiniWidget ID="MiniWidget1" runat="server" />
</ItemTemplate>
</asp:ListView>
Mini Widget User Control
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="MiniWidget.ascx.cs" Inherits="UpdatePanelInListViewTest.MiniWidget" %>
<asp:UpdatePanel ID="ajaxWidget" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:LinkButton ID="lnkTest" runat="server" onclick="lnkTest_Click">Test</asp:LinkButton>
<asp:Label ID="lblTest" runat="server" Text=""></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
I've tried different permutations of this; i.e. having the button outside the panel and adding a trigger etc but I just cannot get it to update.
It appears that because the user control is within an item template of the parent list view it causes the update panel to not update for some reason...
The problem is to do with when you call the databind method within ListUserControl.
Moving lstTest.DataBind(); so that it executes within the Page_Load rather than the Page_PreRender fixes the issue for your simple test web app.
have u tried:
<asp:UpdatePanel ID="ajaxPanel" runat="server" ChildrenAsTriggers="true" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnTest" />
</Triggers>
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<asp:Button ID="btnTest" runat="server" Text="Test" onclick="btnTest_Click" />
</ContentTemplate>
</asp:UpdatePanel>
I have an update panel that has UpdateMode of Conditional and ChildrenAsTriggers set to false. I only want a few controls to cause an asynchronous postback:
<asp:UpdatePanel ID="updPnlMain" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
// ...
<asp:Repeater ID="rptListData" runat="server">
<ItemTemplate>
<asp:Button ID="btnAddSomething" runat="server" OnClick="btnAddSomething_Click" />
</ItemTemplate>
</asp:Repeater>
// ...
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnAddSomething" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
I am getting the following error when I try and load this page:
A control with ID 'btnAddSomething' could not be found for the trigger in UpdatePanel 'updPnlMain'.
Since my btnAddSomething control is in a repeater and might not be there right away it acts like it is nonexistent. How can I get around this?
Because your control is in the repeater control and it is out of scope to the Trigger collection. By the way you don't need to add trigger because your button control is already in the UpdatePanel, it will update when you click the button.
Edit: There is a solution if you really want to update your updPnlMain updatepanel. You can put in another updatepanel and put your button in that panel. e.g.
<asp:UpdatePanel ID="updButton" runat="server" UpdateMode="Conditional">
<asp:Button ID="btnAddSomething" runat="server" OnClick="btnAddSomething_Click" />
</ContentTemplate>
and then simply call the updPnlMain.Update(); method in btnAddSomething_Click event.
It will actually do what you are looking for :)