Placeholder inside an UpdatePanel - asp.net

A little pseudo code to provide some background:
I have an ASPX with a placeholder and a button
When the button is clicked it adds a web user control (uc1) to my placeholder
The uc has a button
When clicked it adds a different user controls (uc2) to the placeholder
Stepping through the code, if I look at the placeholder.controls.count before and after the button-click in #4 the count increases by one, as you would expect.
The problem is that the uc2 added in #4 doesn't appear on the screen. So, I wrapped my placeholder in an UpdatePanel. I've never used one before. So, I could refresh the placeholder after the uc2 was added.
relevant ASPX code
<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server></ajaxToolkit:ToolkitScriptManager>
<ajaxToolkit:TabContainer ID="tcNavigation" runat="server" ActiveTabIndex="0">
<ajaxToolkit:TabPanel ID="tpWebMerchandising" runat="server" HeaderText="WEB">
<ContentTemplate>
<table cellpadding="3" cellspacing="0" border="0">
<tr>
<td valign="top" class="label">Attributes</td>
<td>
<asp:UpdatePanel runat="server" id="UpdatePanel1" updatemode="Conditional">
<ContentTemplate>
<asp:PlaceHolder ID="phAttributes" runat="server"></asp:PlaceHolder><br />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnAddAttribute" runat="server" Text="Add Attribute" /> | <asp:Button ID="btnCreateAttribute" runat="server" Text="Create Attribute" />
</td>
</tr>
</table>
</ContentTemplate>
</ajaxToolkit:TabPanel>
</ajaxToolkit:TabContainer>
relevant ASCX code
For Each ctrl As Control In Parent.Page.Controls
For Each ctrl2 As Control In ctrl.Controls
For Each ctrl3 As Control In ctrl2.Controls
For Each ctrl4 As Control In ctrl3.Controls
For Each ctrl5 As Control In ctrl4.Controls
If InStr(ctrl5.GetType.ToString(), "UpdatePanel") > 0 Then 'UPDATE PANEL
up = ctrl5
End If
For Each ctrl6 As Control In ctrl5.Controls 'CONTENT TEMPLATE
For Each ctrl7 As Control In ctrl6.Controls 'PLACE HOLDER
If ctrl7.GetType.ToString() = "System.Web.UI.WebControls.PlaceHolder" Then
phAttributes = ctrl7
End If
Next
Next
Next
Next
Next
Next
Next
Dim ctrlAttributes As New AttributeControl
ctrlAttributes.AttributeName = attrName
ctrlAttributes.AttributeValue = attrValue
ctrlAttributes.ID = "ctrlAttribute-" & attrName
phAttributes.Controls.Add(ctrlAttributes)
I tried this...
up.Update()
and this...
Me.Page.RegisterStartupScript("AutoPostBackScript", "__doPostBack('UpdatePanel1', '');")
The goal is to refresh the placeholder so the new ctrlAttributes is displayed on screen.

First of all, use Parent.FindControl instead of this mess of foreach-es.

Related

Textbox focus is not working when AjaxControlToolkit TabContainer is used in the page

I have an asp web page with a text box and I want to set focus on it on load event in code behind in this way:
Protected Shadows Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Page.SetFocus(Me.txtPassword)
'txtPassword.Focus()
End Sub
Both methods are working unless I add a tabcontainer to my page. Below is my web page:
in the header I am registering the AjaxControlToolkit in this way:
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
Then in my page I have the text box and the tab container:
<table style="width: 100%" id="tblnssf" cellspacing="0" cellpadding="0" runat="server">
<tr>
<td style="width: 97px; height: 40px">
<asp:TextBox ID="txtPassword" TabIndex="1" runat="server" Width="85px" TextMode="Password"></asp:TextBox>
</td>
</tr>
</table>
<cc1:TabContainer ID="TabContainer1" runat="server" Width="100%">
<cc1:TabPanel ID="TabPanel1" runat="server" HeaderText="Header 1">
<HeaderTemplate> Header 1 </HeaderTemplate>
<ContentTemplate> test 1 </ContentTemplate>
</cc1:TabPanel>
<cc1:TabPanel ID="TabPanel2" runat="server" HeaderText="Header 2">
<HeaderTemplate>Header 2</HeaderTemplate>
<ContentTemplate>test 2</ContentTemplate>
</cc1:TabPanel>
</cc1:TabContainer>
When I remove the tab container, both focus methods work properly... And If I add a button and handle its click event from the server side, also focus is working even with the presence of the tab container... It seems this issue is fired only on load event handled from code behind (server side)
This is really weird and I don't know how to solve it. I really need to set focus onload event from server side not from client side because I am adding some conditions ... Any helps?

Issue in displaying loader gif via Ajax

I have a below section which is implemented to display loader gif associated to the update panel
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="updPnlPromotion">
<ProgressTemplate>
<img alt="" src="Image/Ajaxloader.gif" />
</ProgressTemplate>
</asp:UpdateProgress>
This is the update panel which contains the dropdown which is a data bound control binded on the radio button checked changed event, but rather than partial postback and the display of loader gif, the entire page posts back.
<asp:UpdatePanel ID="updPnlPromotion" runat="server" UpdateMode="Always">
<ContentTemplate>
<td align="left" style="width: 20%;background-color:#CDCD9C">
<asp:radiobutton ID="rdbPromotion" runat="server" Text="New Promotion" AutoPostBack="true" GroupName="TacPlan" OnCheckedChanged="rdbPromotion_OnCheckedChanged" style="font-weight:bold" />
</td>
<td align="left" style="width:30%; vertical-align:middle; background-color:#EBEBEB; text-align:center">
<asp:DropDownList runat="server" ID="ddlPromotion" Width="95%"></asp:DropDownList>
</td>
<td>
<asp:Label Text="*" ForeColor="Red" Visible="false" runat="server" ID="lblPromoPlanMandatory"></asp:Label>
</td>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="rdbPromotion" EventName="CheckedChanged" />
</Triggers>
</asp:UpdatePanel>
I don't believe there's an issue with the code you've posted. I created a new ASPX page and copied your code into it. It works as expected (I added a counter to monitor load events):
Here's the code behind I used for testing this:
Public Sub rdbPromotion_OnCheckedChanged(sender As Object, e As EventArgs) Handles rdbPromotion.CheckedChanged
System.Threading.Thread.Sleep(2000)
End Sub
Private Sub Default5_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.counter.Text = Integer.Parse(Me.counter.Text) + 1
End Sub
Seems like a longshot, but maybe the browser you're testing with doesn't support partial rendering, or ASP.NET doesn't think that it does?:
http://ajax.asp.net/ajax/documentation/live/mref/P_System_Web_UI_ScriptManager_EnablePartialRendering.aspx
I have found the solution to my problem, upon reviewing the web.config file I found the weird setting xhtmlConformance mode="Legacy" there which was basically stopping the page to ajaxify somehow, by removing it, it works as expected.

Using TextBox TextChanged event to enable or disable a button control in asp.net

I am using an asp TextBox control with its TextChanged event and my goal is to capture text as a user enters it. If there are one or more characters entered, I would like a button control to be enabled without the user having to leave the TextBox control.
My source code for the TextBox on the aspx page is
<asp:TextBox ID="NewSpendingCategoryTextBox" MaxLength="12" runat="server"
AutoPostBack="True"
OnTextChanged="NewSpendingCategoryTextBox_TextChanged"
ViewStateMode="Enabled" >
</asp:TextBox>
and my source code on the code behind page is
Protected Sub NewSpendingCategoryTextBox_TextChanged(sender As Object, e As System.EventArgs) Handles NewSpendingCategoryTextBox.TextChanged
Dim strSpendingCategoryTextBox As String = Nothing
strSpendingCategoryTextBox = NewSpendingCategoryTextBox.Text
If strSpendingCategoryTextBox.Length <= 0 Then
Me.NewSpendingCategoryInsertButton.Enabled = False
Else 'strSpendingCategoryTextBox.Length > 0
Me.NewSpendingCategoryInsertButton.Enabled = True
End If 'strSpendingCategoryTextBox.Length <= 0
End Sub
So it appears I have to use javascript to enable or disable the insert button. Can someone guide me on how to get an element within a table? The table sits in a Panel as well.
below is the aspx code...
<asp:Panel ID="AddSpendingCategoryPanel" Visible="false" runat="server">
<table class="AddNewTable">
<tbody>
<tr>
<td>
<asp:Label ID="lblSpend" runat="server"
Text="Spending Category:">
</asp:Label>
</td>
<td>
<asp:TextBox ID="txtSpend" MaxLength="12"
runat="server"
AutoPostBack="True"
OnTextChanged="txtSpend_TextChanged"
OnKeyDown="return CheckSpendTextBoxValue()"
ViewStateMode="Enabled" >
</asp:TextBox>
</td>
</tr>
<tr>
<td>
<asp:Button CssClass="frmbtn" ID="btnInsertSpend"
runat="server" Text="Insert" />
</td>
<td>
<asp:Button CssClass="frmbtn" ID="btnCancelSpend"
runat="server" Text="Cancel"
CausesValidation="False" />
</td>
</tr>
</tbody>
</table>
</asp:Panel>
Run this code in the OnKeyPress event or consider JavaScript. The textbox does not fire the Text_Changed event til Tab or Enter are used.
Simplify the boolean check.
Me.NewSpendingCategoryInsertButton.Enabled = (NewSpendingCategoryTextBox.Text.Length <> 0)
I'm not sure exactly how you would do it. But the ASP.NET code is executed on the server that is hosting the web page.
I'd highly recommended doing it on JavaScript which can be run client side. Hopefully this article is of use to you.
How to check if a textbox is empty using javascript

Do a Button Click from Code behide

I have a gridview which lists Tools and Access values. To edit I have an edit imagebutton on each row. I have an OnRowBound method which assigns an OnClick attribute to each button so that I will know which record I need to edit.
The code is
Protected Sub ChangeFirstRowIcon(ByVal Sender As Object, ByVal e As GridViewRowEventArgs) Handles gv_AccessRights.RowDataBound
'This sub fires on each gridview row created...
'It first checks that the row is a data row (as opposed to Header, Footer etc.)
'If ib_Edit is true then change add an attribut to button with aid, tid and ac values attached.
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ib_Edit As ImageButton = e.Row.FindControl("ib_Edit")
Dim lb_AccessID As Label = e.Row.FindControl("lb_AccessID")
Dim hd_ToolID As HiddenField = e.Row.FindControl("hd_ToolID")
Dim hd_AccessCode As HiddenField = e.Row.FindControl("hd_AccessCode")
If ib_Edit IsNot Nothing Then
ib_Edit.Attributes.Add("onClick", "proxyClick('" & lb_AccessID.Text & "', '" & hd_ToolID.Value & "', '" & hd_AccessCode.Value & "')")
End If
End If
End Sub
I'm using a hidden proxy button to show a modal popup which the user will use to edit a record... (the same popup will be used to add a new access record... but that will come later). So having passed my details to proxyClick I set values to controls within the modal popup. The javascript is....
<script type="text/javascript">
function proxyClick(aid, tid, ac) {
document.getElementById('hd_AccessID').value = aid;
document.getElementById('hd_ToolIDMod').value = tid;
document.getElementById('hd_AccessCodeMod').value = ac;
document.getElementById('but_SetModalDetails').click();
}
</script>
For reference the main bits of the markup are....
<table class="border">
<tr>
<td>
<asp:Button ID="but_SetModalDetails" runat="server" Style="display: none" Text="Set modal details" ClientIDMode="Static" UseSubmitBehavior="true" />
<asp:Button ID="but_HiddenProxy" runat="server" Style="display: none" Text="Hidden Proxy Button for Modal Popup" ClientIDMode="Static" />
</td>
<td class="rt">
<asp:Button ID="but_AddTool" runat="server" AccessKey="A" CssClass="butGreen" Text="Add Tool" ToolTip="Add Tool - Alt A" />
</td>
</tr>
</table>
<asp:ModalPopupExtender ID="mpx_AddEditAccess" runat="server" CancelControlID="but_Cancel"
BehaviorID="pn_AddEditAccess" PopupControlID="pn_AddEditAccess" TargetControlID="but_HiddenProxy"
BackgroundCssClass="modalBackground" />
<asp:Panel ID="pn_AddEditAccess" runat="server" Width="500px" CssClass="modalPopup"
Style="display: block">
<div class="box">
<h2>
<asp:Label ID="lb_ModTitle" runat="server"></asp:Label>
</h2>
<asp:HiddenField ID="hd_AccessID" runat="server" ClientIDMode="Static"></asp:HiddenField>
<div class="block">
<asp:UpdatePanel ID="up_Access" runat="server" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddl_ToolName" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<table>
<tr>
<th class="p66 rt">
Tool Name:
</th>
<td class="p66">
<asp:HiddenField ID="hd_ToolIDMod" runat="server" ClientIDMode="Static" />
<asp:DropDownList ID="ddl_ToolName" runat="server" AutoPostBack="true" AppendDataBoundItems="True"
DataSourceID="SqlDS_Tools" DataTextField="ToolName" DataValueField="ToolID" OnSelectedIndexChanged="ddl_ToolName_SIC">
<asp:ListItem Text="Please Select..." Value="0"></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDS_Tools" runat="server" ConnectionString="<%$ ConnectionStrings:ToolsConnString %>"
SelectCommand="SELECT [ToolID], [ToolName] FROM [tbl_Tools] WHERE ([Redundant] = #Redundant)">
<SelectParameters>
<asp:Parameter DefaultValue="False" Name="Redundant" Type="Boolean" />
</SelectParameters>
</asp:SqlDataSource>
<asp:RequiredFieldValidator ID="rfv_ddl_ToolName" runat="server" ControlToValidate="ddl_ToolName"
CssClass="error" Display="Dynamic" ErrorMessage="Please Select Tool Name" InitialValue="0">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<th class="p66 rt">
Access Rights:
</th>
<td class="p66">
<asp:HiddenField ID="hd_AccessCodeMod" runat="server" ClientIDMode="Static" />
<asp:DropDownList ID="ddl_AccessCode" runat="server" Enabled="false">
<asp:ListItem Text="No Access" Value="0"></asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td class="p66">
<asp:Button ID="but_Cancel" runat="server" Text="Cancel" />
</td>
<td class="p66 rt">
<asp:Button ID="but_Save" runat="server" Text="Save" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</asp:Panel>
As you can see I have implemented two hidden buttons but_SetModalDetails and but_HiddenProxy. but_SetModalDetails has some codebehind which sets a couple of dropdown lists (one populated from a datasource, the other is populated dynamically based on the value of the first. The codebehind is...
Protected Sub but_SetModalDetails_Click(ByVal sender As Object, ByVal e As EventArgs) Handles but_SetModalDetails.Click
If hd_AccessID.Value = "0" Then
lb_ModTitle.Text = "Assigning Access Rights to:"
ddl_ToolName.SelectedIndex = 0
ddl_AccessCode.SelectedIndex = 0
ddl_AccessCode.Enabled = False
Else
lb_ModTitle.Text = "Edit Access Rights to:"
ddl_ToolName.SelectedValue = hd_ToolIDMod.Value
ddl_ToolName.Enabled = False
SqlStr = "SELECT AccessID AS ddlValue, AccessText as ddlText FROM tbl_AccessCodes WHERE ToolID = " & hd_ToolIDMod.Value
PopulateDDLvalue(ddl_AccessCode, SqlStr)
ddl_AccessCode.SelectedValue = hd_AccessCodeMod.Value
ddl_AccessCode.Enabled = True
End If
'NOW I NEED TO SIMULATE but_HiddenProxy Click
End Sub
As you can see at the end I need to simulate a click of but_HiddenProxy so that the modalPopup is shown populated with the correct data.
Any Ideas? Thanks
After all that... I was able to do everything in codebehind...
I only needed one hidden button but_HiddenProxy.
In the gridview instead of setting an onClick attribute for each edit image button I just set a commandname of 'AccessEdit' (don't use 'Edit'). I then had a method that handled the gridview.RowCommand event. This found the various info I needed by using findControl on the selected row. These values were then used to populate the dropdowns in the popup and then use the show command to make the popup visible.
One bit that did stump me for a while was why my RowCommand was not triggering when an imagebutton was clicked. I'd forgotten that I had validation in the modal which stopped the RowCommand being executed. I stuck a CausesValidation="false" in the imagebutton and all was OK.
Talk about using a hammer to crack a nut!

Ajax callback UpdatePanel.Update() still reloading whole page

I have code in an Update Panel and even though on a button click i am inserting data into a db and simply calling Updatepanel.Update() the whole page is reloaded:
Gifts.ASPX
<table style="width:100%;">
<tr>
<td>
<asp:Label ID="Label2" runat="server" Text="Gift"></asp:Label>
</td>
<td>
<asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="txtNewGift" runat="server"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
</td>
</tr>
<tr>
Gifts.aspx.CS
protected void cmdAddGift_Click(object sender, EventArgs e)
{
OleDbConnection objConn = new OleDbConnection(DataSource);
Random r = new Random();
int giftID = r.Next(1200, 14000);
OleDbCommand objCommand = new OleDbCommand("Insert into Gifts (GiftID, Description) values (" + giftID + ",'" + txtNewGift.Text + "')", objConn);
ExecuteCommand(objCommand);
PopulateGifts(objConn);
txtNewGift.Text = "";
UpdatePanel3.Update();
}
Any ideas why this whole page would reload instead of just the textbox getting update?
Where is the button in the above example? Inside or outside the UpdatePanel. If it is outside you will need to add it to the triggers collection of the UpdatePanel.
Also you only need to call UpdatePanel.Update() if you are changing the content of an UpdatePanel other than the one that caused the (Partial) postback.
As a side note (and personal crusade), it is recommended that a using statement is put around your DB connection.
With the markup below, the following will happen:
btnInnerPart is inside the update panel, so it will automatically cause a partial postback
btnInnerFull will cause a full postback as it has a PostBackTrigger in the trigger collection
btnOuterPart will cause a partial postback as it has an AsyncPostBackTrigger in the trigger collection
btnOuterFull will cause a full postback as it is outside the UpdatePanel
Markup:
<asp:UpdatePanel runat="server">
<ContentTemplate>
<!-- Content -->
<asp:Button runat="server" ID="btnInnerPart" Text="Inner Part" />
<asp:Button runat="server" ID="btnInnerFull" Text="Inner Full" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnOuterPart" />
<asp:PostBackTrigger ControlID="btnInnerFull" />
</Triggers>
</asp:UpdatePanel>
<asp:Button runat="server" ID="btnOuterFull" Text="Outer Full" />
<asp:Button runat="server" ID="btnOuterPart" Text="Outer Part" />
Where is the button on Gifts.ASPX? If you put the button inside the UpdatePanel or use triggers you don't need to call UpdatePanel3.Update(); from the code behind.
Also, You need to have a ScriptManager object on your page. Do you have one?
please check tag of update panel...you have to specify the trigger controls for update panel on on which the update panel will get update

Resources