ASP.Net Checkbox control nested within repeater control...HELP!!

B

Brian Miller

So much for ASP.Net controls being easier to set up than classic ASP
ones. I'm trying to set up a page that will contain a couple grids
with 4 checkboxes per row, with the number of rows dependent on my
number of records returned. I figured for this approach, I would use
a repeater control, with the asp:checkbox controls nested within each
row, like as follows:

<asp:Repeater ID="Section1Repeater" Runat="server"
OnItemDataBound="Section1Repeater_ItemDataBound">
<ItemTemplate>
<tr bgcolor=white>
<td align=center>
<asp:Label ID="Section1Activity" Runat="server"></asp:Label>
</td>
<td align=left>
<asp:Label ID="Section1ActivityDescription"
Runat="server"><%#Container.DataItem("Description")%></asp:Label>
</td>
<td align=center>
<asp:Label ID="Section1ActivityTemplate"
Runat="server"><%#Container.DataItem("Template")%></asp:Label>
</td>
<td align=center>
<asp:CheckBox ID="Section1SmallCheckbox" Runat="server" />
</td>
<td align=center>
<asp:CheckBox ID="Section1MediumCheckbox" Runat="server" />
</td>
<td align=center>
<asp:CheckBox ID="Section1LargeCheckbox" Runat="server" />
</td>
<td align=center>
<asp:CheckBox ID="Section1TechnologyOnlyCheckbox"
Runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>

After constructing the HTML tables with repeaters such as this one
within them, I realized there is no direct approach apparently to
binding checkboxes to data. I can't bind each checkbox individually
due to not knowing the number of records that will be returned, so how
can I go about this, and still be able to wire up check/uncheck events
so I can update the associated datarow with each? BTW, the fields
that will be associated with each of the 4 checkboxes are contained in
the same table, however, they are not group items and need to be
evaluated separately. Any help would be very greatly appreciated!

Thanks,
Brian
 
J

Jos

Brian said:
So much for ASP.Net controls being easier to set up than classic ASP
ones. I'm trying to set up a page that will contain a couple grids
with 4 checkboxes per row, with the number of rows dependent on my
number of records returned. I figured for this approach, I would use
a repeater control, with the asp:checkbox controls nested within each
row, like as follows:

<asp:Repeater ID="Section1Repeater" Runat="server"
OnItemDataBound="Section1Repeater_ItemDataBound">
<ItemTemplate>
<tr bgcolor=white>
<td align=center>
<asp:Label ID="Section1Activity" Runat="server"></asp:Label>
</td>
<td align=left>
<asp:Label ID="Section1ActivityDescription"
Runat="server"><%#Container.DataItem("Description")%></asp:Label>
</td>
<td align=center>
<asp:Label ID="Section1ActivityTemplate"
Runat="server"><%#Container.DataItem("Template")%></asp:Label>
</td>
<td align=center>
<asp:CheckBox ID="Section1SmallCheckbox" Runat="server" />
</td>
<td align=center>
<asp:CheckBox ID="Section1MediumCheckbox" Runat="server" />
</td>
<td align=center>
<asp:CheckBox ID="Section1LargeCheckbox" Runat="server" />
</td>
<td align=center>
<asp:CheckBox ID="Section1TechnologyOnlyCheckbox"
Runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>

After constructing the HTML tables with repeaters such as this one
within them, I realized there is no direct approach apparently to
binding checkboxes to data. I can't bind each checkbox individually
due to not knowing the number of records that will be returned, so how
can I go about this, and still be able to wire up check/uncheck events
so I can update the associated datarow with each? BTW, the fields
that will be associated with each of the 4 checkboxes are contained in
the same table, however, they are not group items and need to be
evaluated separately. Any help would be very greatly appreciated!

Thanks,
Brian

1) Binding the checkboxes is easy. Try this code:
<asp:CheckBox ID="cb1" Runat="server"
Checked=<%#Container.DataItem("myBooleanField")%>/>

2) Updating is a little more complicated.
You could iterate all the RepeaterItems on postback, like this
(I use VB.NET):

Dim ri As RepeaterItem
For Each ri In Section1Repeater.Items
Dim cb1 As Checkbox=CType(ri.FindControl("cb1"),Checkbox)
If(cb1.Checked) Then ' do some updating here...
Next ri
 
B

Brian Miller

Thanks for the reply, Jos. I have the binding working on page load,
however, I am having the main issue with the update portion of things.
Since there is no record key value to assign to each of the
checkboxes, when iterating through the controls on PostBack, how can
you tell which checkboxes belong to which records? I figured I would
spin through all of the checkbox controls in a loop like you posted,
but wondered if perhaps I should create a custom checkbox control with
a "RecordKey" value so that on PostBack I can evaluate each item for
updating the record desired.
 
J

Jos

Brian said:
Thanks for the reply, Jos. I have the binding working on page load,
however, I am having the main issue with the update portion of things.
Since there is no record key value to assign to each of the
checkboxes, when iterating through the controls on PostBack, how can
you tell which checkboxes belong to which records? I figured I would
spin through all of the checkbox controls in a loop like you posted,
but wondered if perhaps I should create a custom checkbox control with
a "RecordKey" value so that on PostBack I can evaluate each item for
updating the record desired.

I guess there's an easier way, but I once worked around this
by "hiding" the RecordKey inside the checkbox's ID, like this:

<asp:checkbox ID='cb_<%# DataBinder.Eval(Container.DataItem,"RecordKey") %>'
....

I use the prefix "cb_" because RecordKeys are usually numbers, which are not
allowed for ID's.

On postback, you can then extract the RecordKey from the checkbox's ID.
 
B

Brian Miller

Jos said:
I guess there's an easier way, but I once worked around this
by "hiding" the RecordKey inside the checkbox's ID, like this:

<asp:checkbox ID='cb_<%# DataBinder.Eval(Container.DataItem,"RecordKey") %>'
...

I use the prefix "cb_" because RecordKeys are usually numbers, which are not
allowed for ID's.

On postback, you can then extract the RecordKey from the checkbox's ID.

I decided for lack of better approaches for storage, to create a
custom web control with the checkbox class as its base. So basically,
my CustomCheckBox control has all properties of the original control,
plus a RecordKey. I figured that would do the trick, as I could spin
through the values for each of these controls either on the
CheckChanged event, or in worst case scenario, call a function to do
that from the PostBack = True section of my Page_Load. I've traced
through my code in all cases, and noticed the order of the events as
they happen upon my save button click event (Page_Load - PostBack,
CheckChanged event for each checkbox changed in my repeater,
btnSave_Click). Even on the postback, the RecordKey value for each
checkbox is returning as an all-zero guid (as I am using guids for
record keys in this application). I've tried everything from using
the FindControl method to cycling through each control in the
repeater, using nested For loops to get to every control's properties,
in each of these events/functions with no luck. Is there some way I
can cause the control to keep the RecordKey property? I know the
value is being assigned initially, as I also tested output of a label
next to each checkbox, and the record key is showing correctly for
each. I guess the big question is whether the value is being lost due
to the checkbox being contained within the repeater, or if it's just
not maintaining viewstate despite setting properties to
EnableViewState = True for the checkbox and/or the repeater it's
contained within. Thanks again for your help!

Brian
 
B

Brian Miller

One other quick note...I tried the following approach:

<asp:checkbox ID='cb_<%#
DataBinder.Eval(Container.DataItem,"RecordKey") %>'
....

and it triggers a parser error message that it is not a valid
identifier. Looks like it will not allow any data to be included into
the ID for the control.
 
B

Brian Miller

Here's a solution I found to this checkbox issue, if anyone else
encounters this:

Use the Attributes property to add a new attribute to the checkbox
control in the repeater's ItemDataBound event. Use the FindControl
method to get the checkbox control, then use
MyCheckBox.Attributes.Add("RecordKey", value) to set it. In my case,
since the viewstate was losing the values I was using, I set the
checkbox Text property to the RecordKey value, then used that to
assign the attribute value. I then set the text to String.Empty on
the following line, so just the checkbox shows in each column once the
page is rendered. A page-level SQL string was used, built in the
CheckedChanged event. After concatenating the SQL for all updated
checkboxes, then the SQL string is executed in the Save function.
Code snippets are below:

In the repeater control's ItemDataBound event:
Dim myControl As Control
Dim myCheckbox As CheckBox

For Each myControl In e.Item.Controls
If TypeOf myControl Is CheckBox Then
myCheckbox = DirectCast(myControl, CheckBox)
myCheckbox.Attributes.Add("MyRecordKey",
myCheckbox.Text)
myCheckbox.Text = String.Empty
End If
Next

In each checkboxes CheckedChanged event:
Dim myCheckbox As CheckBox = DirectCast(sender, CheckBox)
Dim recordKey As String = myCheckbox.Attributes("MyRecordKey")

If myCheckbox.Checked = True Then
'Update value to true
SQLString &= "UPDATE TableName SET FieldName = 'True' "
SQLString &= "WHERE TableName = '" & recordKey & "'; "
Else
'Update value to false
SQLString &= "UPDATE TableName SET FieldName = 'False' "
SQLString &= "WHERE TableName = '" & recordKey & "'; "
End If

The save button's Click event occurs after the CheckedChanged event
has built the SQL, so execute the SQL in that event's code.

Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top