Losing update panel trigger from databound gridview in tab container - asp.net

I'm having some trouble getting a command link in a gridview to maintain it's ability to change tabs after the initial postback. So below you will see the structure of my content (heavily simplified):
<ajaxToolkit:TabContainer runat="server" ID="tabBody">
<ajaxToolkit:TabPanel runat="server" ID="tabPanel1">
<ContentTemplate>
<asp:UpdatePanel runat="server" ID="updPanel1">
<ContentTemplate>
<asp:Gridview runat="server" ID="grd1" OnRowCommand="grd1_RowCommand" OnRowDataBound="grd1_RowDataBound">
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkChangePanels" runat="server" CommandArgument='<%#Eval("id") %>' CommandName="gotopanel2" Text='<%#Eval("FirstName") & " " & Eval("LastName")%>' />
</ItemTemplate>
</asp:TemplateField>
</asp:Gridview>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajaxToolkit:TabPanel>
<ajaxToolkit:TabPanel runat="server" ID="tabPanel2">
<ContentTemplate>
<asp:UpdatePanel runat="server" ID="updPanel2">
<ContentTemplate>
<asp:Gridview runat="server" ID="grd2">
</asp:Gridview>
</ContentTemplate>
</asp:UpdatePanel>
</ContentTemplate>
</ajaxToolkit:TabPanel>
</ajaxToolkit:TabContainer>
In order to fill the gridview on panel 1, there is a search box which the user types into and I call a function to bind a linq query to it.
Now I add the rowcommand as a postback trigger on rowdatabound:
Protected Sub grd1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim lb As LinkButton = CType(e.Row.FindControl("lnkChangePanels"), LinkButton)
If Not lb Is Nothing Then
ToolkitScriptManager1.RegisterPostBackControl(lb)
End If
End If
End Sub
Then here is the code I have to trigger the tab panel to change (and do some other stuff):
Protected Sub grd1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles grd1.RowCommand
Dim id = e.CommandArgument.ToString()
Select Case e.CommandName
Case "gotopanel2"
eventDetails(id, "C")
tabBody.ActiveTab = tabPanel2
End Select
End Sub
This causes a proper postback and changes the tab, everything works as intended. But if I go back to the first tab and try clicking another row in gridview 1, nothing happens.
Is there a way to structure this so the that either the tab can change without losing the postback trigger or am I going about this all wrong?
Thanks.

Postback trigger is not lost. Problem is caused by individual UpdatePanels in each tab.
Put entire TabContainer within UpdatePanel and you can remove UpdatePanels from tabs (but you don't have to). Make sure that UpdateMode of that new panel is set to "Always".
I think the reason why it does not change in your example is that UpdatePanel only refreshes it's own content and attribute that decides if tab is visible or not is set for div (tabPanel) outside that UpdatePanel. When you go back to tab with grid you do it client-side by clicking on it and that's when it goes wrong.
To get to the bottom of the problem and figure out why it does work during the first postback you would probably have to debug ajax toolkit javascript for TabContainer control.

Related

Dropdown autopost inside updatepanel never enters code behind SelectedIndexChanged event

This is a difficult scenerio to explain, so I coded up a simple example.
<asp:UpdatePanel runat="server" ID="upTest" ChildrenAsTriggers="true"
UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="ddlTest" runat="server" AutoPostBack="true"></asp:DropDownList>
<br /><br />
In page: <asp:TextBox runat="server" ID="txtTest" Columns="50" Text="OnLoad</asp:TextBox>
<br />
<br />
<asp:Button runat="server" ID="btnTest" Text="Click it" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddlTest" />
</Triggers>
</UpdatePanel>
Code-Behind
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack Then
BindDropDown(Request.Form(ddlTest.UniqueID))
Else
BindDropDown(0)
End If
End Sub
Public Sub BindDropDown(val As Integer)
ddlTest.Items.Add(New ListItem("", 0))
ddlTest.Items.Add(New ListItem("One", 1))
ddlTest.Items.Add(New ListItem("Two", 2))
ddlTest.Items.Add(New ListItem("Three", 3))
ddlTest.Items.Add(New ListItem("Four", 4))
ddlTest.SelectedValue = val
End Sub
Private Sub ddlTest_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ddlTest.SelectedIndexChanged
txtTest.Text = "Dropdown changed"
End Sub
Private Sub btnTest_Click(sender As Object, e As System.EventArgs) Handles btnTest.Click
txtTest.Text = "Button clicked"
End Sub
Also to note, I have EnableViewState="false" and ClientIdMode="Static" for the page.
When I click the button the partial postback occurs and the textbox has the expected value of 'Button Clicked'
When I change the dropdown the partial postback occurs, however the textbox does not have the expected value of 'Dropdown changed' because the code in ddlTest_SelectedIndexChanged is never hit (breakpoint placement on that line of code also never hits)
In the larger scope of my project this is the crux of the problem and I can't determine why this event is never hit (the core problem is when I load a dynamic user control, the data in the control is bound correctly, but then is overridden with the pre-post data after the user control is loaded - the override is occurring somewhere in the post back events). It appears to me it has something to do with the binding of the dropdown and where it happens in the page cycle, but I haven't been able to nail anything down, nor come up with google solutions.
One odd thing I did notice when looking at the post in Firebug - the EVENTTARGET value for the dropdown was the UniqueId of the dropdown, but the EVENTTARGET value is empty for the button click. My brain is thinking there is some connection here.
FYI - I have come up with a work around that seems to do the trick. I set autopostback on dropdown to false, and using jQuery I assign the change event on the dropdown to fire the button click - which causes the postback and fires btn_click event in code.
I solved the initial issue here by moving the dropdown fill to the init event and then letting .NET load the selected value from view state
However in doing this, now the selectedindex event fires on EVERY postback.

asp:ImageButton in Gridview OnClick event not working

I've spent quite a while searching this problem, there are some other similar threads online but none have helped me fix it.
I have a GridView with an ImageButton within it, the imagebutton has an OnClick function but that event is never reached when it is clicked, below is my gridview:
<asp:GridView ID="gridBuildings" runat="server" AutoGenerateColumns="False"
GridLines="none" ShowFooter="false" ShowHeader="false"
Width="100%">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton runat="server" ID="cmdBuy"
ImageUrl="~/images/button.jpg"
OnClick="ImageButton_Click"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and here's the code-behind (I've removed the extra content, the response.redirect is never hit when the ImageButton is clicked)
Protected Sub ImageButton_click(ByVal sender As Object, ByVal e As ImageClickEventArgs)
response.redirect("test.aspx")
Dim row As GridViewRow = Me.gridBuildings.SelectedRow
(etc ... )
End Sub
There is a form runat="server" tag in the master page, as well as an asp:UpdatePanel and an asp:AjaxScriptManager I have a feeling the problem might be something to do with a postback but just can't work it out - any help would be appreciated.
Thanks!
Make sure you are not rebinding the grid every page load. If you rebind, the event will never fire. Wrap the binding statement in an if not ispostback block.

ASP.NET Ajax Text Box with Button not firing

Hey just wondering if my syntax is wrong here
<asp:UpdatePanel ID="UpdatePanel2"
runat="server"
UpdateMode="Always">
<ContentTemplate>
<asp:textbox id="searchProductName" runat="server"></asp:textBox> <asp:Button ID="btnProductSearch" runat="server" Text="Search Product Name" CssClass="search" OnClick="ProductSearch_Click" UseSubmitBehavior="true" CausesValidation="false" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnProductSearch" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
and my OnClick method
Protected Sub ProductSearch_Click(ByVal sender As Object, ByVal e As EventArgs)
' Filter by ProductName
If searchProductName.Text.Length > 0 Then
srcProductListPerCustomer.FilterExpression = " (productName like '%" + searchProductName.Text.ToString & "%')"
productListTable.DataBind()
Else
srcProductListPerCustomer.FilterExpression = ""
productListTable.DataBind()
End If
End Sub
The problem is nothing is happening when I click on the button. The button works fine without the Ajax
Your button doesn't need to be in an UpdatePanel. The controls in a UpdatePanel should be the controls that are to be updated asynchronously. Put your UpdatePanel around the GridView you're updating, and use the AsyncPostBackTrigger in the same way.
It's best to keep UdpatePanels as small as possible; the fewer controls inside them, the less HTML will be sent back from the server (less bandwidth, faster request/response time). PostBackTriggers can refer to controls outside of the UpdatePanel with no problems.

Dynamic Validation Controls Don't Work in Update Panel

I'm dynamically creating validation controls and adding them to an update panel. However the client side validation never fires.
Here is the aspx file:
<div>
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
</ContentTemplate>
<Triggers >
<asp:AsyncPostBackTrigger ControlID ="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
<asp:Button ID="Button1" runat="server" Text="Button" CausesValidation="true"/>
</div>
Here is the code behind:
Dim Survey As New Survey
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Survey.RenderPage(PlaceHolder1)
End Sub
Here is the class that creates the validation control:
Public Class Survey
Public Sub RenderPage(ByVal PlaceHolder As PlaceHolder)
Dim textbox As New TextBox
textbox.ID = "testing"
PlaceHolder.Controls.Add(textbox)
Dim val As New RequiredFieldValidator
val.ControlToValidate = textbox.ID
val.Text = "required"
val.EnableClientScript = True
PlaceHolder.Controls.Add(val)
End Sub
End Class
When you hit next, client side validation never fires. What's really weird is that when you wrap the button inside another update panel, the validation fires (in IE and Firefox, but not in Chrome or Safari).
Anyone have any ideas what's going on? I know that the first versions of Asp.net AJAX didnt support the validation controls, but everything is up to date on my end.
I see there 2 problems
When update panel causes async post back to server it cannot create tree of controls with your dynamic controls - so check that you call RenderPage from Page_Load for ScriptManager.IsInAsyncPostBack == true
There is issue of usage validators under update panel - the scripts must be loaded before update panel works. I can propose you to allocate fictive RequiredFieldValidator under UpdatePanel. Set them Display=none (but not Visible=false !!!) or place to nonexistence ValidationGroup. This allows to render JScript into you page.

Default radio button not triggering an UpdateControl postback

I have three radio buttons on a form - A, B, C. Each of these selections populates a dropdown list with data specific to the option. When the form loads, I set option A to be checked (as the default).
When I select buttons B or C, the AsyncPostBack triggers fine and the dropdown is populated. BUT, subsequently selecting A from either B or C does not trigger the event.
I suspect that because A was checked when the form loaded, the browser is not seeing any "change" to raise the event.
So what can be done to enable the default A button recognise it is being changed from B or C in order to raise the postback?
I have tried both setting the checked state of button A in code on inital loading of the page only (ie IsPostBack is False) and alternatively setting the checked attribute of the radiobutton in the html, with the same results. If I don't default the radio button the functionality works as expected, except I don't have the radio button and dropdown list defaulted when the page first loads.
The html...
<asp:RadioButton ID="radBook" runat="server" AutoPostBack="true" GroupName="grpArticleType" Text="Book" />
<asp:RadioButton ID="radCD" runat="server" AutoPostBack="true" GroupName="grpArticleType" Text="CD" />
<asp:RadioButton ID="radDVD" runat="server" AutoPostBack="true" GroupName="grpArticleType" Text="DVD" />
<asp:UpdatePanel ID="pnlTasks" runat="server" UpdateMode="Conditional" RenderMode="Inline">
<ContentTemplate>
<asp:DropDownList ID="dropShippingSize" runat="server" CssClass="dropdownMandatory"></asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="radBook" />
<asp:AsyncPostBackTrigger ControlID="radCD" />
<asp:AsyncPostBackTrigger ControlID="radDVD" />
</Triggers>
</asp:UpdatePanel>
The code behind...
Sub Page_Load
If Not Me.IsPostBack Then
radBook.Checked = True
End If
End Sub
Private Sub rad_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles radBook.CheckedChanged, radCD.CheckedChanged, radDVD.CheckedChanged
zLoadShippingSizeDropdown()
End Sub
I had the same problem and looked for an answer for hours. This seems to have nothing to do with ViewState or anything similar, but with some kind of incompatibility of using a pre-checked RadioButton as trigger for an Async PostBack.
The work around I found is amazingly easy and worked right away; instead of using the checked=true on the mark-up or myRadioButton.Checked on the server side, I did the following:
Not setting the attribute on Mark-up and add this on the Page_Load event:
if (!IsPostBack)
{
MyRadioButton.InputAttributes["checked"] = "true";
...
}
I hope this helps and saves some people hours of hair pulling :)
I'm guessing you need to need to check if the page is a postback in your load event:
protected void Form_Load(object sender, EventArgs e)
{
if (!Page.IsPostback)
{
// Set radiobutton A...
}
}
We had the same problem and it seems you will have to set the other "checked" property for radio buttons to "false".
So please add the lines
radCD.Checked = False
radDVD.Checked = False
Are you by chance handling viewstate in your code behind as well? If so then you need to handle the AJAX version of it as viewstate can often be lost on AJAX style pages. Try putting your buttons inside the update panel and see if you get the same behaviour if the panel has it's update mode set to conditional. Don't worry about the postback triggers if you do that.
The asynch triggers are only for items inside an update panel. any item outside of a panel will doa full postback by design.
<asp:UpdatePanel ID="pnlTasks" runat="server" UpdateMode="Conditional" RenderMode="Inline">
<ContentTemplate>
<asp:RadioButton ID="radBook" runat="server" AutoPostBack="true" GroupName="grpArticleType" Text="Book" />
<asp:RadioButton ID="radCD" runat="server" AutoPostBack="true" GroupName="grpArticleType" Text="CD" /><asp:RadioButton ID="radDVD" runat="server" AutoPostBack="true" GroupName="grpArticleType" Text="DVD" />
<asp:DropDownList ID="dropShippingSize" runat="server" CssClass="dropdownMandatory">
</asp:DropDownList>
</ContentTemplate>
</asp:UpdatePanel>
WOW, I would have never thought that could be the bug. Saved many hours of frustration.
Thanks Juan going through the carppy Microsoft issue and found a solution for the rest.

Resources