How to Hide a RadioButtonList or CheckBoxList ListItem in ASP.NET





1.00/5 (4 votes)
May 2, 2006
3 min read

94253

495
This article demonstrates how to hide RadioButtonList or CheckBoxList ListItems in ASP.NET without creating your own custom web control
Introduction
With the advent of ASP.NET about five years ago Microsoft created several built-in Web Forms controls and among them are the RadioButtonList and CheckboxList. These two controls have a pretty robust and intuitive class structure but are lacking in a quite pratical aspect: the ability to hide their individual ListItems!
Background
I must admit that hiding individual ListItems in a RadioButtonList or CheckBoxList is not something that developers have to do on a regular basis. However, when are you required to hide them for pratical reasons it can become quite frustrating. In one such case I needed to have a default value for a RadioButtonList that I didn't want the user to see but that I could reference programmatically using the SelectedItem property. After trying several other approaches and searching the web for other solutions it became abundantly clear to me that I would have to create my own solution. The result I believe is a nice workaround that is flexible enough for developers to use in their existing applications without having to make a reference to an external .dll file or web control library.
My Initial approach to Hiding ListItems... which didn't work
My initial approach to tackling this problem was to reference a ListItem object in the RadioButtonList or CheckBoxList control's Items collection and add a style attribute that would set its display style to "none". Now a reasonable person would think that this would work because it doesn't cause a compile or runtime error. However, when the control is rendered as HTML to the browser the attributes specified in the source code are not rendered!!!
Here was my initial idea of hiding a ListItem which did not work:
Public Shared Sub HideListItem(ByRef RbList As RadioButtonList)
'This code doesn't work although logically you might think that it would!
RbList.Items(0).Attributes.Add("style", "display='none;'")
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
HideListItem(Me.rbGender)
End Sub
When the page loads and you view the HTML source of the page this is what it looks like:
<table id="rbGender" border="0" style="width:136px;">
<tr>
<td><input id="rbGender_0" type="radio" name="rbGender" value="-1" /><label for="rbGender_0">-1</label></td>
<td><input id="rbGender_1" type="radio" name="rbGender" value="0" /><label for="rbGender_1">Female</label></td>
<td><input id="rbGender_2" type="radio" name="rbGender" value="1" /><label for="rbGender_2">Male</label></td>
</tr>
</table>
You will notice that the attribute "style=display='none;'" is no where to be found!
An appproach that works! Hiding the ListItem by using dynamically generated DHTML
Becuase my style attribute was not being rendered as I specified in my code. I decided to take another approach. By tapping into my knowledge of DHTML I decided to dynamically generate some DHTML that would hide the ListItems for me.
Check out the code below for additional details:
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
'Get the JavaScript code that will hide the ListItem
Dim jsCode As String = HideRadioButtonListItem(Me.rbGender)
'use RegisterStartupScript to make sure
'that this javascript is placed after the RadioButtonList HTML has rendered
Me.RegisterStartupScript("HideListItems", jsCode)
End Sub
'Use this method if you want to hide the first item in the list
Public Function HideRadioButtonListItem(ByRef RbList As RadioButtonList) As String
Dim IndexesHide() As String = {"0"}
Return HideRadioButtonListItems(RbList, IndexesHide)
End Function
'Use this method if you want to hide multiple Items of various indexes
'For example: HideRadioButtonListItems(Me.rbGender, "0,2".Split(","c))
'Would hide the first and third items in the RadioButtonList
Public Function HideRadioButtonListItems(ByRef RbList As RadioButtonList, ByVal IndexesToHide() As String) As String
Dim HideColumnOrRowBasedOnRepeatDirection As String = ""
'Determine whether an HTML row or column is to be hidden
'based on the Repeat direction
If RbList.RepeatDirection = RepeatDirection.Horizontal Then
HideColumnOrRowBasedOnRepeatDirection = "td"
ElseIf RbList.RepeatDirection = RepeatDirection.Vertical Then
HideColumnOrRowBasedOnRepeatDirection = "tr"
End If
'Get the ClientID that will be used when the control is rendered to the client in HTML
Dim CtrlClientID As String = RbList.ClientID
'The .NET Framework recommends that you use a StringBuilder class instead of a String DataType
'when dealing with potentially large strings
Dim JScriptCodeString As New System.Text.StringBuilder
'Build the javascript that will do the hiding of the items
JScriptCodeString.Append(" <script language=" + Chr(34) + "javascript" + Chr(34) + "> " & vbCrLf)
JScriptCodeString.Append(" var rbTable;" & vbCrLf)
JScriptCodeString.Append(" rbTable = document.getElementById(""" & CtrlClientID & """);" & vbCrLf)
JScriptCodeString.Append(" if ((rbTable == null) || (rbTable == undefined)) { } else { " & vbCrLf)
JScriptCodeString.Append(" var NestedLabels;" & vbCrLf)
JScriptCodeString.Append(" NestedLabels = rbTable.getElementsByTagName(""")
JScriptCodeString.Append(HideColumnOrRowBasedOnRepeatDirection & """);" & vbCrLf)
For i As Integer = 0 To IndexesToHide.Length - 1
JScriptCodeString.Append(" NestedLabels[" & IndexesToHide(i) & "].style.display = ""none"";" & vbCrLf)
Next
JScriptCodeString.Append(" } " & vbCrLf)
JScriptCodeString.Append(" </script> " & vbCrLf)
Return JScriptCodeString.ToString()
End Function
Here is the ASP.NET HTML source:
<body >
<form id="Form1" method="post" runat="server">
<P>Choose Gender (optional) : </P>
<P><asp:RadioButtonList id=rbGender runat="server" Width="200px" RepeatDirection="Horizontal">
<asp:ListItem Value="-1">-1</asp:ListItem>
<asp:ListItem Value="0">Female</asp:ListItem>
<asp:ListItem Value="1">Male</asp:ListItem>
</asp:RadioButtonList></P>
</form>
</body>
Here is the HTML source that is rendered to the browser when the page is run:
<body >
<form name="Form1" method="post" action="WebForm1.aspx" id="Form1">
<input type="hidden" name="__VIEWSTATE" value="dDwtMTQ2MTEwNDc7Oz5KPbuB9pD1EtgvbuBPmJmyEQ9ORQ==" ID="Hidden1"/>
<P>Choose Gender (optional) : </P>
<P><table id="rbGender" border="0" style="width:200px;">
<tr>
<td><input id="rbGender_0" type="radio" name="rbGender" value="-1" /><label for="rbGender_0">-1</label></td>
<td><input id="rbGender_1" type="radio" name="rbGender" value="0" /><label for="rbGender_1">Female</label></td>
<td><input id="rbGender_2" type="radio" name="rbGender" value="1" /><label for="rbGender_2">Male</label></td>
</tr>
</table></P>
<script language="javascript">
var rbTable;
rbTable = document.getElementById("rbGender");
if ((rbTable == null) || (rbTable == undefined)) { } else {
var NestedLabels;
NestedLabels = rbTable.getElementsByTagName("td");
NestedLabels[0].style.display = "none";
}
</script>
</form>
</body>
Basically, the code takes in a reference to a RadioButtonList and uses its ClientID (the server control identifier generated by ASP.NET before the control is rendered to the client's browser) property to access it by using the document.getElementById Javascript function. Then I determine if the repeat direction is Horizontal or Vertical and get all columns or rows for the HTML element. Since the ListItem's indexes match exactly to the collection of columns or rows in a rendered RadioButtonList HTML table I am able to hide the rows or columns based on the specified index the developer decides to pass in.
Hey what about the CheckBoxList?
I didn't forget about our good ol' friend the CheckboxList. In order to keep this article concise I neglected to add the code for the CheckboxList. As you might already know, these two controls are similar in that they both have an Items collection and a RepeatDirection property. I was hoping they both inherited from a BaseClass that would have these two key properties. Unfortunately, the ListControl class from which they inherit, has a Items collection property but doesn't have a .RepeatDirection property. So I just decided to create seperate overloaded methods for each of them.
When you download the source and project files you will see methods devoted to both the CheckboxList and RadioButtonList in addition to other cool ways of implementing this functionality into your applications. Since I am well versed in both C# and VB I have provided the source files in both C# and VB.NET. So you can just copy and paste as needed.
Conclusion
I hope this approach can benefit you if you need to hide or show ListItems in a CheckboxList or RadioButtonList. Please feel free to build upon this concept and extend it to create other functionality for your individual ListItems. Some cool incarnations of this concept could be disabling individual ListItems or adding custom client-side onclick events.
Live long and code proper!
History
No revisions thus far...