tmccrank
asked on
Distribution of items from an ArrayList to a particular instance of a Repeater
Hi,
I'm trying to populate a RadioButtonList (each RadioButton is a possible multiple-choice answer) that is within a Repeater (each being a question). The RBL is being populated by an ArrayList. The format should look something like this:
Repeater1 (i.e. Question 1)
RB1 (i.e. multiple-choice 1)
RB2 (m-c 2) etc...
RB3
RB4
RB5
Repeater2
RB1
RB2
RB3
RB4
RB5
Right now, I have all the answers for ALL the questions showing up under EACH question:
Repeater1
RB1
RB2
RB3
RB4
RB5
RB1
RB2
RB3
RB4
RB5
Repeater2
RB1
RB2
RB3
RB4
RB5
RB1
RB2
RB3
RB4
RB5
How can I take specific strings from the ArrayList and populate specific instances of a repeater with them? Here's what my ItemDataBound code for the Repeater looks like:
Public Sub rptQuestions_ItemDataBound (ByVal sender As Object, ByVal e As System.Web.UI.WebControls. RepeaterIt emEventArg s) Handles rptQuestions.ItemDataBound
Dim lt As ListItemType = e.Item.ItemType
If lt = ListItemType.Item OrElse lt = ListItemType.AlternatingIt em Then
Dim strAnswers As String = CType(e.Item.DataItem, String)
If Not strAnswers Is Nothing Then
Dim rblAnswers As RadioButtonList = CType(e.Item.FindControl(" rblAnswers "), RadioButtonList)
If Not rblAnswers Is Nothing Then
Dim alAnswers As ArrayList
alAnswers = DA.PopulateAnswers(CInt(Re quest.Quer yString(0) ))
rblAnswers.DataSource = alAnswers
rblAnswers.DataBind()
End If
End If
End If
End Sub
Hope this isn't too confusing.
Jens
I'm trying to populate a RadioButtonList (each RadioButton is a possible multiple-choice answer) that is within a Repeater (each being a question). The RBL is being populated by an ArrayList. The format should look something like this:
Repeater1 (i.e. Question 1)
RB1 (i.e. multiple-choice 1)
RB2 (m-c 2) etc...
RB3
RB4
RB5
Repeater2
RB1
RB2
RB3
RB4
RB5
Right now, I have all the answers for ALL the questions showing up under EACH question:
Repeater1
RB1
RB2
RB3
RB4
RB5
RB1
RB2
RB3
RB4
RB5
Repeater2
RB1
RB2
RB3
RB4
RB5
RB1
RB2
RB3
RB4
RB5
How can I take specific strings from the ArrayList and populate specific instances of a repeater with them? Here's what my ItemDataBound code for the Repeater looks like:
Public Sub rptQuestions_ItemDataBound
Dim lt As ListItemType = e.Item.ItemType
If lt = ListItemType.Item OrElse lt = ListItemType.AlternatingIt
Dim strAnswers As String = CType(e.Item.DataItem, String)
If Not strAnswers Is Nothing Then
Dim rblAnswers As RadioButtonList = CType(e.Item.FindControl("
If Not rblAnswers Is Nothing Then
Dim alAnswers As ArrayList
alAnswers = DA.PopulateAnswers(CInt(Re
rblAnswers.DataSource = alAnswers
rblAnswers.DataBind()
End If
End If
End If
End Sub
Hope this isn't too confusing.
Jens
ASKER
Hi Sachit,
The .aspx page code looks like this:
-------------------------- ------
<body MS_POSITIONING="GridLayout ">
<form id="Form1" method="post" runat="server">
<asp:repeater id="rptQuestions" runat="server" OnItemDataBound="rptQuesti ons_ItemDa taBound">
<HeaderTemplate>
<ol>
</HeaderTemplate>
<ItemTemplate>
<li>
<%# Container.DataItem %>
</li>
<asp:RadioButtonList ID="rblAnswers" Runat="server"></asp:Radio ButtonList >
</ItemTemplate>
<FooterTemplate>
</ol>
</FooterTemplate>
</asp:repeater>
</form>
</body>
-------------------------- ------
As you can see, I have a RadioButtonList nested in a Repeater control. Each control gets its data from separate tables: one table for the questions (the repeater), and one for the list of possible answers (the RBL). A DataReader is used to read the data into separate ArrayLists which then are the data sources for each control. I want the RBL control (not the CheckBoxList) since the user should be able to choose only one of five answers for each question.
So, my main question is, how do I populate each question with the list of answers that are relevant to only that question?
Here's the Page_Load event code:
-------------------------- ------
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'retrieve ArrayList
Dim alQuestions As ArrayList
alQuestions = DA.PopulateQuestions(CInt( Request.Qu eryString( 0)))
'bind the questions repeater to the alQuestions ArrayList
rptQuestions.DataSource = alQuestions
rptQuestions.DataBind()
End Sub
-------------------------- ------
And here is the ItemDataBound code for populating the RadioButtonList:
-------------------------- ------
Public Sub rptQuestions_ItemDataBound (ByVal sender As Object, ByVal e As System.Web.UI.WebControls. RepeaterIt emEventArg s) Handles rptQuestions.ItemDataBound
Dim lt As ListItemType = e.Item.ItemType
If lt = ListItemType.Item OrElse lt = ListItemType.AlternatingIt em Then
Dim strAnswers As String = CType(e.Item.DataItem, String)
If Not strAnswers Is Nothing Then
Dim rblAnswers As RadioButtonList = CType(e.Item.FindControl(" rblAnswers "), RadioButtonList)
If Not rblAnswers Is Nothing Then
Dim alAnswers As ArrayList
alAnswers = DA.PopulateAnswers(CInt(Re quest.Quer yString(0) ))
rblAnswers.DataSource = alAnswers
rblAnswers.DataBind()
End If
End If
End If
End Sub
-------------------------- ------
Thanks
Jens
The .aspx page code looks like this:
--------------------------
<body MS_POSITIONING="GridLayout
<form id="Form1" method="post" runat="server">
<asp:repeater id="rptQuestions" runat="server" OnItemDataBound="rptQuesti
<HeaderTemplate>
<ol>
</HeaderTemplate>
<ItemTemplate>
<li>
<%# Container.DataItem %>
</li>
<asp:RadioButtonList ID="rblAnswers" Runat="server"></asp:Radio
</ItemTemplate>
<FooterTemplate>
</ol>
</FooterTemplate>
</asp:repeater>
</form>
</body>
--------------------------
As you can see, I have a RadioButtonList nested in a Repeater control. Each control gets its data from separate tables: one table for the questions (the repeater), and one for the list of possible answers (the RBL). A DataReader is used to read the data into separate ArrayLists which then are the data sources for each control. I want the RBL control (not the CheckBoxList) since the user should be able to choose only one of five answers for each question.
So, my main question is, how do I populate each question with the list of answers that are relevant to only that question?
Here's the Page_Load event code:
--------------------------
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'retrieve ArrayList
Dim alQuestions As ArrayList
alQuestions = DA.PopulateQuestions(CInt(
'bind the questions repeater to the alQuestions ArrayList
rptQuestions.DataSource = alQuestions
rptQuestions.DataBind()
End Sub
--------------------------
And here is the ItemDataBound code for populating the RadioButtonList:
--------------------------
Public Sub rptQuestions_ItemDataBound
Dim lt As ListItemType = e.Item.ItemType
If lt = ListItemType.Item OrElse lt = ListItemType.AlternatingIt
Dim strAnswers As String = CType(e.Item.DataItem, String)
If Not strAnswers Is Nothing Then
Dim rblAnswers As RadioButtonList = CType(e.Item.FindControl("
If Not rblAnswers Is Nothing Then
Dim alAnswers As ArrayList
alAnswers = DA.PopulateAnswers(CInt(Re
rblAnswers.DataSource = alAnswers
rblAnswers.DataBind()
End If
End If
End If
End Sub
--------------------------
Thanks
Jens
ASKER
Maybe this would be easier if I pulled down the data from the two SQL tables into one ArrayList instead of two.
If I do that I need to figure out how to populate the Questions Repeater AND the Answer RBL (nested in the Repeater) from the ArrayList...
If I do that I need to figure out how to populate the Questions Repeater AND the Answer RBL (nested in the Repeater) from the ArrayList...
What i m noticing here is that u r creating separate arraylists for binding questions.
In ItemDataBound, plz verify that DA.PopulateAnswers method is returning answers for respective question because ItemDataBound event would execute once for each question.
Say one question is there with quesitionNo as 1 and 1A, 1B, 1C, 1D and 1E are possible options for question 1 then when ItemDataBound is getting executed for question 1, ur method DA.PopulateAnswers should set the arraylist with records 1A to 1E only.
Regards
Sachit.
In ItemDataBound, plz verify that DA.PopulateAnswers method is returning answers for respective question because ItemDataBound event would execute once for each question.
Say one question is there with quesitionNo as 1 and 1A, 1B, 1C, 1D and 1E are possible options for question 1 then when ItemDataBound is getting executed for question 1, ur method DA.PopulateAnswers should set the arraylist with records 1A to 1E only.
Regards
Sachit.
ASKER
Sachit,
Yes, DA.PopulateAnswers is returning an ArrayList of answers for each question. Here's the code:
-------------------------- --
Public Function PopulateAnswers(ByVal QuestID As Integer) As ArrayList
Dim alPopAnswers As New ArrayList
Dim strPopAnswers As String = ("SELECT a.Answers, a.QuestionsID, q.QuestionsID, q.ModuleID, m.ModuleID ")
strPopAnswers = strPopAnswers & ("FROM Answers a INNER JOIN Questions q ")
strPopAnswers = strPopAnswers & ("ON a.QuestionsID = q.QuestionsID ")
strPopAnswers = strPopAnswers & ("INNER JOIN Modules m ON q.ModuleID = m.ModuleID WHERE m.ModuleID='") & QuestID + 1 & ("'")
Dim drPopAnswers As SqlDataReader
Dim commPopAnswers As New SqlCommand(strPopAnswers, conNEM)
Try
'open connection
conNEM.Open()
'execute reader, then close connection
drPopAnswers = commPopAnswers.ExecuteRead er(Command Behavior.C loseConnec tion)
'iterate through result set, add to ArrayList
While drPopAnswers.Read()
alPopAnswers.Add(drPopAnsw ers("Answe rs"))
End While
Catch ex As Exception
ex.ToString()
Finally
'close datareader
drPopAnswers.Close()
End Try
Return alPopAnswers
End Function
-------------------------- ---------
To use your analogy, if I have 3 Questions, what I'm ending up with is:
Question 1: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
Question 2: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
Question 3: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
So the answers for all 3 questions are showing up for each question. Of course it should be like this:
Question 1: 1A, 1B, 1C, 1D, 1E
Question 2: 2A, 2B, 2C, 2D, 2E
Question 3: 3A, 3B, 3C, 3D, 3E
Get it? Do you think it would be better if I have just one ArrayList (with the questions and answers from the SQL DB tables) and somehow iterate through it to populate the Questions Repeater and the Answers RadioButtonList? If so, how could that be done?
If I stay with two ArrayLists, I somehow need to loop through the Answers ArrayList where the loop recognizes which Question index it's on. The problem here is that the Questions are in another ArrayList. That's why I'm thinking it might be better to have one ArrayList instead of two.
Thanks and regards,
Jens
Yes, DA.PopulateAnswers is returning an ArrayList of answers for each question. Here's the code:
--------------------------
Public Function PopulateAnswers(ByVal QuestID As Integer) As ArrayList
Dim alPopAnswers As New ArrayList
Dim strPopAnswers As String = ("SELECT a.Answers, a.QuestionsID, q.QuestionsID, q.ModuleID, m.ModuleID ")
strPopAnswers = strPopAnswers & ("FROM Answers a INNER JOIN Questions q ")
strPopAnswers = strPopAnswers & ("ON a.QuestionsID = q.QuestionsID ")
strPopAnswers = strPopAnswers & ("INNER JOIN Modules m ON q.ModuleID = m.ModuleID WHERE m.ModuleID='") & QuestID + 1 & ("'")
Dim drPopAnswers As SqlDataReader
Dim commPopAnswers As New SqlCommand(strPopAnswers, conNEM)
Try
'open connection
conNEM.Open()
'execute reader, then close connection
drPopAnswers = commPopAnswers.ExecuteRead
'iterate through result set, add to ArrayList
While drPopAnswers.Read()
alPopAnswers.Add(drPopAnsw
End While
Catch ex As Exception
ex.ToString()
Finally
'close datareader
drPopAnswers.Close()
End Try
Return alPopAnswers
End Function
--------------------------
To use your analogy, if I have 3 Questions, what I'm ending up with is:
Question 1: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
Question 2: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
Question 3: 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, 3A, 3B, 3C, 3D, 3E
So the answers for all 3 questions are showing up for each question. Of course it should be like this:
Question 1: 1A, 1B, 1C, 1D, 1E
Question 2: 2A, 2B, 2C, 2D, 2E
Question 3: 3A, 3B, 3C, 3D, 3E
Get it? Do you think it would be better if I have just one ArrayList (with the questions and answers from the SQL DB tables) and somehow iterate through it to populate the Questions Repeater and the Answers RadioButtonList? If so, how could that be done?
If I stay with two ArrayLists, I somehow need to loop through the Answers ArrayList where the loop recognizes which Question index it's on. The problem here is that the Questions are in another ArrayList. That's why I'm thinking it might be better to have one ArrayList instead of two.
Thanks and regards,
Jens
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Sachit,
Thanks for your help. I looks like using a DataTable is the way to go, I was hoping to stay with using ArrayLists since they're such light-weight objects compared to DataSets. There seems to be a growing number of people out there who are actively advising against using DataSets under ANY circumstances!
I'm not sure yet how to use the RowFilter property, but that's another problem that I'll try to figure out.
Jens
Thanks for your help. I looks like using a DataTable is the way to go, I was hoping to stay with using ArrayLists since they're such light-weight objects compared to DataSets. There seems to be a growing number of people out there who are actively advising against using DataSets under ANY circumstances!
I'm not sure yet how to use the RowFilter property, but that's another problem that I'll try to figure out.
Jens
Scenario should be like, take a repeater control with a label and checkboxlist (label to display question, checkboxlist to display answers) and bind that repeater with the datasource(table populated with questions and possible options for those questions).
I don't think u need to have a separate repeater control for each question.
If my understanding is not clear about ur question then plz correct me.
Regards
Sachit.