Updating placeholder during runtime - asp.net

here is the problem I am having with placeholder:
I have a repeater and within that repeater, I have an item template. Now this template is formatted with a couple of tables, but for this question I have removed them to make things easier to read:
<asp:Repeater ID="Repeater1" OnItemDataBound="R1_ItemDataBound" runat="server">
<ItemTemplate>
<asp:PlaceHolder ID="phAnswers" runat="server"></asp:PlaceHolder>
</ItemTemplate>
</asp:Repeater>
Then, on the event OnItemDataBound, I create a new placeholder, bind it to the existing on (phAnswers), however the placeholder is not updated with the radiobuttons/textboxs that are created:
Dim rdList As New RadioButtonList
Dim newRadio As New RadioButton
If (e.Item.ItemType = ListItemType.Item) Or _
(e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim tempPH As PlaceHolder
tempPH = e.Item.FindControl("phAnswers")
For x As Integer = 0 To (t_MC.Count - 1)
newRadio = New RadioButton
newRadio.ID = "Answer" + x.ToString
newRadio.Text = t_MC(x).Value
rdList.Controls.Add(newRadio)
Next
tempPH.Controls.Add(rdList)
Any ideas why phAnswers is not updated with the new tempPH placeholder?
Cheers

OnItemDataBound may be too late to add controls. Try it in OnItemCreated and see if that helps. It's a quick test - just change your repeater event declaration like this:
OnItemCreated="R1_ItemDataBound"
If this idea doesn't help, you can easily switch it back.
Edit - I just noticed something. To populate a RadioButtonList, you should use ListItems, like this:
ListItem item - new ListItem("your text", "your value");
rdList.Items.Add(item);
This is probably why your RadioButtonList did not appear, but lone radio buttons worked.

Try using a Panel instead of a PlaceHolder

Related

grid view checkbox and javascript not informing server side code?

I've got a asp.net gridview and inside of the grid view I have a check box at the header of the grid view like so:
<HeaderTemplate>
<asp:CheckBox Width="1px" ID="HeaderLevelCheckBox" AutoPostBack="true" OnCheckedChanged="SelectAllRows" runat="server" />
</HeaderTemplate>
This gives me a nice little check box at the top of the grid view...the event OnCheckedChanged calls a function called SelectAllRows that looks like this:
Public Sub SelectAllRows(ByVal sender As Object, ByVal e As System.EventArgs)
Dim gr As GridViewRow = DirectCast(DirectCast(DirectCast(sender, CheckBox).Parent, DataControlFieldCell).Parent, GridViewRow)
Dim h As CheckBox = DirectCast(gr.FindControl("HeaderLevelCheckBox"), CheckBox)
For Each Row As GridViewRow In Me.gvLineItems.Rows
Dim cb As CheckBox = CType(Row.FindControl("chkSelector"), CheckBox)
cb.Checked = h.Checked
Next
End Sub
So if I click this header checkbox it checks all of the items in the gridview, and if I uncheck it, it unchecks all the items in the gridview. This works fine...but what doesnt seem to work is if the page loads up and I check the grid view header checkbox to true and it selects all the items in the gridview, then i click a button such as a DELETE button that calls some server side code. That code simply loops through the grid view and checks if the checkbox has been checked, if it is it calls code to delete an item. Something to this effect:
For Each Row As GridViewRow In Me.gvLineItems.Rows
Dim cb As CheckBox = CType(Row.FindControl("chkSelector"), CheckBox)
Dim lID As Long = Convert.ToInt32(gvLineItems.DataKeys(Row.RowIndex).Value)
If cb IsNot Nothing AndAlso cb.Checked Then
'ok to delete
End If
Next
When I place a watch and debug on this it seems that the value cb is always false...
Even though it was set to true when I clicked the header checkbox...
What gives ???
The actual chkSelector in the grid view is for each row and it looks like this:
<ItemTemplate>
<asp:CheckBox ID="chkSelector" runat="server" onclick="ChangeRowColor(this)" />
</ItemTemplate>
Also I am already checking for postback..that is not the issue, remember chkSelector does not autopostback...
Thanks
I doubt, your gridview is rebinding on a Delete button click, because a click of the Delete button loads the page first where it will rebind and your checkbox's become unchecked again. I think you are binding your gridview some where in the page load event.
You have to do something like this
If(!Page.IsPostBack)
{
//Gridview Binding Code goes here....
}
Edit: Alternatively you can check/uncheck rows using javascript. It will save a round trip to the server side and resolve your current issue as well.
Here is complete code
<script language="javascript" type="text/javascript">
function SelectAll(spanChk,grdClientID) {
var IsChecked = spanChk.checked;
var Chk = spanChk;
Parent = document.getElementById(grdClientID);
var items = Parent.getElementsByTagName('input');
for(i=0;i<items.length;i++)
{
if(items[i].type=="checkbox")
{
items[i].checked=document.getElementById(spanChk).checked;
}
}
}
<HeaderTemplate>
<asp:CheckBox runat="server" ID="chkHeader" onclick="SelectAll('<%=chkHeader.ClientID %>, <%=yourGrid.ClientID %>') />
</HeaderTemplate>

Is there an easy way to add a "--Select--" option to a DataBound DropDownList?

I have a DataBound DropDownList that is loading fine, but i'd like to insert another item that says "--Select--" or something instead of having the first DataBound item automatically display.
Is there an easy way to do this or do I need to manually add a dummy item?
Here is my code:
MyContext fc = new MyContext ();
ddl.DataSource = fc.SomeTable;
ddl.DataBind();
Alternatively, add a default item in the markup and set the "AppendDataBoundItems" property to true.
<asp:DropDownList ID="ddl" runat="server" AppendDataBoundItems="true">
<asp:ListItem Value="" Text="---Please Select---"></asp:ListItem>
</asp:DropDownList>
After you do the databind do:
ddl.Items.Insert(0, "---Select---");
This will add it as the first item in the list.
Alternatively, you can add a new ListItem instead of a string, so you can have an actual value instead of a string as drop down list value.
So you can do something like:
ddl.Items.Insert(0, new ListItem("---Select---", Guid.Empty.ToString());

Getting value in footer template from code behind-Repeater

I have a repeater like this:
<asp:Repeater runat="server" ID="pde">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<asp:Literal runat="server" ID="literal1"></asp:Literal>
</ItemTemplate>
<FooterTemplate><asp:Literal runat="server" ID="literal2"></asp:Literal></FooterTemplate>
</asp:Repeater>
Now in literal2 I want to get the value from code behind.But I am not able to get the literal2 in code behind.Any idea how to get this?
You should be able to access it by accessing the last RepeaterItem in your repeater which will be your footer. Then do a search, using FindControl, on the RepeaterItem for any control you are looking for.
Using your example above do:
Literal controlYouWant = pde.Controls[pde.Controls.Count - 1].FindControl("literal2") as Literal;
You can break down the statements to:
// This will get you the footer
RepeaterItem item = pde.Controls[pde.Controls.Count - 1];
// From here you finds any control you want within the RepeaterItem.
Literal controlYouWant = item.FindControl("literal2") as Literal;
First search through items in repeater and only take the footer item type and discard the others. Take a look to the following code.
foreach(RepeaterItem item in repeterName.Controls)
{
if (item.ItemType != ListItemType.Footer) continue;
var lblMyLabel = ((Label)item.FindControl("lblMyLabel"));
lblMyLabel.Text = "I found it!!!";
}

Setting LinkButton Title in ASP.Net Wizard Sidebar Template

Playing around with customizing the appearance of the Wizard control in ASP.Net, and I've found out how to disable the sidebar buttons using the SideBarTemplate and catching the OnItemDataBound event. All pretty easy. What I want to do now is to modify the text of the rendered LinkButton to prefix the step name with something like ">>" for the current step.
So, in my ItemDataBound event handler for the SideBarList, I have the following code:
Dim stepCurrent As WizardStep = e.Item.DataItem
Dim linkCurrent As LinkButton = e.Item.FindControl("SideBarButton")
If Not stepCurrent Is Nothing Then
Trace.Write("SideBar", "Current Step = " & stepCurrent.Wizard.ActiveStep.Name)
Trace.Write("Sidebar", "Link Button = " & linkCurrent.Text)
linkCurrent.Enabled = False
If stepCurrent.Wizard.ActiveStepIndex = e.Item.ItemIndex Then
linkCurrent.Style.Add(HtmlTextWriterStyle.Color, "#000000")
linkCurrent.Style.Add(HtmlTextWriterStyle.FontWeight, "bold")
linkCurrent.Text.Insert(0, ">> ")
End If
End If
However, what I find is the trace output is showing an empty string for the lunkbutton text, but the style changes work.
Am I trying to set the text in the wrong place?
Thanks
I did not find any way to change "SideBarButton" text property that is why I added
another link button control in SelectedItemTemplate to DataList and set visible="fasle" in SideBarButton. SelectedItemTemplate will be used to render item in sidebar for current wizard step.
<ItemTemplate>
<asp:LinkButton ID="SideBarButton" runat="server"/>
</ItemTemplate>
<SelectedItemTemplate>
<asp:LinkButton ID="ActiveSideBarButton" runat="server">
<asp:LinkButton Visible="false" ID="SideBarButton"unat="server"/>
</SelectedItemTemplate>
In OnItemDataBound event do something like
Dim stepCurrent As WizardStep = e.Item.DataItem
If stepCurrent.Wizard.ActiveStepIndex = e.Item.ItemIndex Then
Dim linkCurrent As LinkButton = e.Item.FindControl("ActiveSideBarButton")
linkCurrent.Style.Add(HtmlTextWriterStyle.Color, "#000000")
linkCurrent.Style.Add(HtmlTextWriterStyle.FontWeight, "bold")
LinkCurrent.Text = stepCurrent.Title;
linkCurrent.Text.Insert(0, ">> ")
End If
SideBarButton will not be rendered because of visible="false" and only ActiveSideBarButton for current step will be rendered with parameters you need.

AutoCompleteExtender control in a repeater

I have an AutoCompleteExtender AjaxControlToolkit control inside a repeater and need to get a name and a value from the web service. The auto complete field needs to store the name and there is a hidden field that needs to store the value. When trying to do this outside of a repeater I normally have the event OnClientItemSelected call a javascript function similiar to
function GetItemId(source, eventArgs)
{
document.getElementById('<%= ddItemId.ClientID %>').value = eventArgs.get_value();
}
However since the value needs to be stored in a control in a repeater I need some other way for the javascript function to "get at" the component to store the value.
I've got some JavaScript that might help you. My ASP.Net AutoComplete extender is not in a repeater, but I've modified that code to detect the ID of the TextBox you are going to write the erturned ID to, it should work (but I haven't tested it all the way through to post back).
Use the value from 'source' parameter in the client side ItemSelected method. That is the ID of the calling AutoComplete extender. Just make sure that you assign an ID the hidden TextBox in the Repeater Item that is similar to the ID of the extender.
Something like this:
<asp:Repeater ID="RepeaterCompareItems" runat="server">
<ItemTemplate>
<ajaxToolkit:AutoCompleteExtender runat="server"
ID="ACE_Item"
TargetControlID="ACE_Item_Input"
...other properties...
OnClientItemSelected="ACEUpdate_RepeaterItems" />
<asp:TextBox ID="ACE_Item_Input" runat="server" />
<asp:TextBox ID="ACE_Item_IDValue" runat="server" style="display: none;" />
</ItemTemplate>
</asp:Repeater>
Then the JS method would look like this:
function ACEUpdate_CustomerEmail(source, eventArgs) {
UpdateTextBox = document.getElementById(source.get_id() + '_IDValue');
//alert('debug = ' + UserIDTextBox);
UpdateTextBox.value = eventArgs.get_value();
//alert('customer id = ' + UpdateTextBox.value);
}
There are extra alert method calls that you can uncomment for testing and remove for production. In a simple and incomplete test page, I got IDs that looked like this: RepeaterCompareItems_ctl06_ACE_Item_IDValue (for the text box to store the value) and RepeaterCompareItems_ctl07_ACE_Item (for the AC Extender) - yours may be a little different, but it looks practical.
Good Luck.
If I understand the problem correctly, you should be able to do what you normally do, but instead of embeding the ClientId, use the 'source' argument. That should allow you to get access to the control you want to update.
Since you are using a Repeater I suggest wiring the OnItemDataBound function...
<asp:Repeater id="rptResults" OnItemDataBound="FormatResults" runat="server">
<ItemTemplate>
<asp:PlaceHolder id="phResults" runat="server" />
</ItemTemplate>
</asp:Repeater>
Then in the code behind use something like
`Private Sub FormatResults(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
Dim dr As DataRow = CType(CType(e.Item.DataItem, DataRowView).Row, DataRow) 'gives you access to all the data being bound to the row ex. dr("ID").ToString
Dim ph As PlaceHolder = CType(e.Item.FindControl("phResults"), PlaceHolder)
' programmatically create AutoCompleteExtender && set properties
' programmatically create button that fires desired JavaScript
' use "ph.Controls.Add(ctrl) to add controls to PlaceHolder
End Sub`
Voila

Resources