I'm OK with C# and VB.nET
I have a DataList (Question) inside the ListView (Section). ListiView is to hold the sections. DataList holds the questions of a section. Let's say I have 3 sections, each section has 2 questions.
<asp:ListView ID="lvSection" runat="server">
<LayoutTemplate>
<div id="itemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<div>
<p><%#Eval("Section")%>
<asp:HiddenField ID="hfSectionId" runat="server" Value='<%#Eval("SectionId")%>' />
<hr />
</p>
</div>
<asp:DataList ID="dlQuestion" runat="server" >
<ItemTemplate>
<asp:Label ID="lblQuestion" runat="server" Text='<%# Eval("Question") %>'></asp:Label>
<asp:HiddenField ID="hfQuestionId" runat="server" Value='<%# Eval("QuestionId") %>' />
</ItemTemplate>
</asp:DataList>
</ItemTemplate>
</asp:ListView>
<br/>
<asp:Button runat="server" Text="Submit" onclick="Submit_Click" />
I'm trying to access the DataList dlQuestion when the button "Submit" is click like this:
Protected Sub Submit_Click(ByVal sender As Object, ByVal e As EventArgs)
'but I need to loop through all DataLists inside the ListView
'Maybe there are ways to get all the DataLists into a collection and then can loop through each one of them
'this will get only one DataList. Here's the pseudocode
Dim question As DataList = lvSection.FindControl("dlQuestion")
For Each item As DataListItem In quest.Items
Dim questionId As HiddenField = item.FindControl("hfQuestionId")
Next
End Sub
But it does not get anything back, question always gets nohting. I think it's because there are 3 DataList inside the ListView now, due to 3 sections, and it cannot find DataList dlQuestion anymore. How do I access these DataLists of ListView from the code behind? I need to loop through each control of the DataList .
Thank you.
You would need to do it as this:
for each item As ListViewDataItem in lvSection.Items
Dim list As DataList = item.FindControl("dlQuestion")
If (list IsNot Nothing) Then
For Each dlItem As DataListItem In quest.Items
Dim questionId As HiddenField = dlItem.FindControl("hfQuestionId")
Next
End If
Next
You have to access the data list in each item in the ListView first, not at the listview level.
Related
I have an aspx page (say MyPage.aspx) where a part of it has the following structure -
<asp:DataList ... >
<HeaderTemplate>
...
</HeaderTemplate>
<ItemTemplate>
<asp:Table ID="table" runat="server">
<asp:TableRow ... >
<asp:TableCell ... >
<asp:ImageButton ID="btnToggle" OnClick="ToggleVisibility" ... >
</asp:TableCell>
...
</asp:TableRow>
</asp:Table>
<asp:DataGrid ... >
</asp:DataGrid>
<asp:Panel ID="panel" runat="server" ...>
<asp:Button ID="button1" runat="server" ...>
<asp:Button ID="button2" runat="server" ...>
</asp:Panel>
</ItemTemplate>
<AlternatingItemTemplate>
...
</AlternatingItemTemplate>
</asp:DataList>
What I am trying to do is that whenever btnToggle is clicked, it toggles visibility of panel. I'm getting the panel in ToggleVisibility() like this -
Dim panelToggle As Panel = sender.Parent.Parent.Parent.Parent.Controls(5)
In this function I'm able to change its Visible property, but its visibility doesn't change on the rendered HTML page (checking through browser).
I'm unable to figure out why is that. Kindly, help.
Thanks.
Add the OnItemCommand event to the DataList that handles the button click. You don't need to add the OnClick event to the button itself anymore.
<asp:DataList ID="DataList1" runat="server" OnItemCommand="DataList1_ItemCommand">
<ItemTemplate>
<asp:Button ID="btnToggle" runat="server" Text="Button" />
<asp:Panel ID="panel" runat="server">
Panel content.
</asp:Panel>
</ItemTemplate>
</asp:DataList>
Then in code behind
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
//find the panel in the datalist item object and cast it back to a panel
Panel panel = e.Item.FindControl("panel") as Panel;
//you can now access it's properties
panel.Visible = false;
}
VB
Protected Sub DataList1_ItemCommand(ByVal source As Object, ByVal e As DataListCommandEventArgs)
'find the panel in the datalist item object and cast it back to a panel
Dim panel As Panel = CType(e.Item.FindControl("panel"),Panel)
'you can now access it's properties
panel.Visible = false
End Sub
I have a RadioButtonList inside of Repeater and I want to select just one option at a time. But for each RadioButtonList created dynamically I can select multiple options in each RadioButtonList.
How can I select one option and deactivate the previous selection?
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="ItemBound">
<ItemTemplate>
<h4><label id="header" runat="server"><%# Eval("Description") %></label></h4>
<asp:UpdatePanel ID="panel" runat="server">
<ContentTemplate>
<asp:RadioButtonList ID="rdo" RepeatDirection="Vertical" runat="server" OnSelectedIndexChanged="rdo_SelectedIndexChanged" AutoPostBack="true" ClientIDMode="AutoID"></asp:RadioButtonList>
</ContentTemplate>
</asp:UpdatePanel>
<br />
</ItemTemplate>
</asp:Repeater>
When a control is rendering in a list bound control, the ID is changed to be unique so JavaScript can work with it. There is a great forum post here about this, and it includes a work-around.
http://forums.asp.net/t/1378112.aspx?RadioButtonList+in+a+Repeater+GroupName
I need to create a dynamically populated two-dimensional array of Button or ImageButton controls.
I want to be able to set the number of buttons in a row.
The table will receive the data from a DataSource control or from code behind, and populate each cell with a Button control with the corresponding value.
For example, if I set then number of columns to 3:
Value1 Value2 Value3
Value4 Value5 Value6
Value7 Value8
What ASP.NET control is best for implementing this?
Thank You.
You can do it by using Repeater Control.
.aspx Page
<div style="width:269px">
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Button runat="server" ID="btn" Text='<%# Eval("Value") %>' />
</ItemTemplate>
</asp:Repeater>
</div>
Here you can set the width of div upon your requirment.
.cs page
DataTable dt = new DataTable();
dt.Columns.Add("Value");
dt.Rows.Add("Value1");
dt.Rows.Add("Value2");
dt.Rows.Add("Value3");
dt.Rows.Add("Value4");
dt.Rows.Add("Value5");
dt.Rows.Add("Value6");
dt.Rows.Add("Value7");
dt.Rows.Add("Value8");
Repeater1.DataSource = dt;
Repeater1.DataBind();
The output will be look like this
You can use DataList for this. RepeatColumns will help you to set the no. of columns.
<asp:DataList ID="dlButtons" runat="server" RepeatDirection="Horizontal" RepeatColumns="3">
<ItemTemplate>
<asp:Button runat="server" ID="button" Text='Your Text' />
</ItemTemplate>
</asp:DataList>
I have an asp Repeater and its DataSource is a DataTable (with data from database).
On the first loading of the page, the DataTable is filled from the db and then its datas are binded to the Repeater.
Then I put the DataTable into the ViewState and on postback I use the DataTable from the ViewState, then it enables me to inject datas in database only after everything has been completed by the user.
Some lines can be added to the Repeater (by adding to the viewstate's DataTable and re-bind).
Here is the Repeater's code :
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:HiddenField ID="HdfHiddenRow" ClientIDMode="Static" runat="server" />
<asp:HiddenField ID="HdfHiddenId" ClientIDMode="Static" runat="server" />
<div style="display:none;">
<asp:Button ID="BtnHiddenButton" runat="server" Text="" OnClick="BtnHiddenButton_Click" />
</div>
<table id="TableEI" style="width: 800px; margin-left:50px;" cellpadding="0" cellspacing="0">
<asp:Repeater ID="Repeat_EffetsIndes" runat="server" OnItemDataBound="Repeat_EffetsIndes_ItemDataBound" >
<ItemTemplate>
<tr>
<td style="width: 431px;">
<asp:Label ID="LblEI" runat="server" />
</td>
<td class="auto-style1">
<asp:CheckBox ID="CheckOui" ClientIDMode="Static" runat="server" Text="Yes" onclick="CheckedLine(this)" />
</td>
<td>
<asp:CheckBox ID="CheckOui1" ClientIDMode="Static" runat="server" Enabled="false" Text="some text1" />
<br />
<asp:CheckBox ID="CheckOui2" ClientIDMode="Static" runat="server" Enabled="false" Text="some text2" />
<br />
<asp:CheckBox ID="CheckOui3" ClientIDMode="Static" runat="server" Enabled="false" Text="some text3" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
.....
[textbox + button to add new row there]
.....
</ContentTemplate>
</asp:UpdatePanel>
Check an example of rows from my Repeater :
http://img4.hostingpics.net/pics/356954example.png
When the 1st checkbox (Yes) is chcked : it enables the 3 right checkboxes.
(this has been done thanks to javascript)
I had to give a unique ID to my 4 checkboxes on each row, and be able to identify which checkboxes have to be enabled when the parent is checked.
I give a unique ID on ItemDataBound event of Repeater.
protected void Repeat_EffetsIndes_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
DataRowView drv = e.Item.DataItem as DataRowView;
((Label)e.Item.FindControl("LblEI")).Text = drv["Suivi_EffetsIndes_Label"].ToString();
CheckBox ParentCheckBox = ((CheckBox)e.Item.FindControl("CheckOui"));
CheckBox ChildCheckBox1 = ((CheckBox)e.Item.FindControl("CheckOui1"));
CheckBox ChildCheckBox2 = ((CheckBox)e.Item.FindControl("CheckOui2"));
CheckBox ChildCheckBox3 = ((CheckBox)e.Item.FindControl("CheckOui3"));
string _IdPrefix = Guid.NewGuid().ToString().Replace("-", "");
// Affectation d'un ID unique à chaque checkbox "Oui"
ParentCheckBox.ID = _IdPrefix;
// Concaténation de l'ID de la checkbox parent (Oui) et d'un chiffre pour identifier les checkboxes.
ChildCheckBox1.ID = _IdPrefix + "1";
ChildCheckBox2.ID = _IdPrefix + "2";
ChildCheckBox3.ID = _IdPrefix + "3";
}
The Problem
When one of the 3 right checkboxes is checked, i would like to directly update the correct value in the ViewState datatable (set field "checked" from 0 to 1).
The problem is that I have some trouble to catch the "CheckedChanged" of the checkboxes, don't know why, and also the "ID" of the checkboxes seem to always set to its default value so i can find them by writing "Repeater.Items[x].FindControl("CheckOui1") for example, and it would not have to be possible because I give them a new ID, and that's thanks to this one that i would like to find which checkbox is checked.
(apologies for my not perfect english writing)
The only problem I see in your code is the fact you're using GUID to set your Checkboxes ID and that it's wrong, because every time you re-bind your repeater or refresh page, the ID will be completely different.
So I advice you to do the following steps:
Remove ClientIDMode property from your checkboxes. By doing this, your checkboxes ID on HTML would be something like this Repeat_EffectsIndes_CheckOui_0 (you can identify each unique ID using Firebug or your browser's option Inspect Element).
On Javascript, verify which checkbox is checked, get the ID and enable the other 3 checkboxes (the same you already have done I suppose). The ID of the other 3 checkboxes will be like Repeat_EffectsIndes_CheckOui_0_CheckOui1 (for the rest is the same, except the last number), the 0 (zero) is the row index.
Finally, on your page code-behind, use the Repeater.Items[x].FindControl("<CheckBoxID>") where <CheckBoxID> is the control ID.
Hope it helps.
Here's my HTML
<asp:UpdatePanel runat="server" ID="panel1" UpdateMode="Conditional">
<ContentTemplate>
<asp:FormView runat="server" ID="formViewUno" DataSourceID="odsBob" DefaultMode="Insert">
<InsertItemTemplate>
<span>Name:</span>
<asp:Literal ID="Literal4" runat="server" Text=" " />
<asp:TextBox runat="server" ID="tbxName" Text='<%# Bind("Name") %>' />
<br />
<span>Age:</span>
<asp:Literal ID="Literal5" runat="server" Text=" " />
<asp:TextBox runat="server" ID="tbxAge" Text='<%# Bind("Age") %>' />
<br />
<span>City:</span>
<asp:Literal ID="Literal6" runat="server" Text=" " />
<asp:TextBox runat="server" ID="tbxCity" Text='<%# Bind("City") %>' />
<br />
<asp:Button ID="Button1" runat="server" CommandName="Insert" Text="Insert" />
</InsertItemTemplate>
</asp:FormView>
<asp:Panel runat="server" ID="msgs">
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
Here's my C#
private void odsBob_Inserted(object sender, ObjectDataSourceStatusEventArgs e)
{
var p = e.ReturnValue as Person;
if (p != null)
{
var msg = new Label
{
Text =
String.Format("{0} [Age:{1}, City:{2}] was successfully added", p.Name, p.Age,
p.City)
};
var br = new LiteralControl { Text = "<br/>" };
msgs.Controls.Add(br);
msgs.Controls.Add(msg);
}
}
How can I persist (add a new one after the insert) the label controls? It is being wiped out. The new one added is added each time correctly. How can I keep the control collection in tact? Thanks for any help.
Cheers,
~ck
It looks like you're dynamically creating a label object during the event handler.
Dynamic controls are problematic because they need to be recreated on every postback. Remember that a postback creates a new instance of your Page object - which means that the controls you added to your last page are gone - your Panel is initialized as empty with each new request, so only the latest literal/label pair will be added.
One solution may be to add all the necessary textual information to Session, and have your Panel generate dynamic labels and literals from whatever is in Session during Prerender.
Another solution would be more complex, but you could have the Panel add labels and literals dynamically during the Init phase. If you can ensure that the same number of controls is added in the same order during Init, then the ViewState for those controls will be properly tracked on each PostBack. You would basically need to store the most recently added label and literal into Session, and have the Panel fetch it out on the next request to ensure it got added back in during Init. You'd also need to store a counter so that the Panel knew how many sets of controls to add during Init.