Click here to Skip to main content
15,892,253 members
Articles / Web Development / ASP.NET
Article

How to group RadioButtons

Rate me:
Please Sign up or sign in to vote.
4.88/5 (132 votes)
11 Aug 2004CPOL2 min read 860.9K   12.8K   246   154
This article describes how to group radio-buttons when using them in DataGrid, DataList, Repeater etc.

Introduction to the problem

'Where is the problem? Haven't you heard about GroupName property?' - you can ask me. Of course, you are right! But...

Let's take an ordinary DataGrid, add a TemplateColumn to its Columns collection, and place a RadioButton control within this column (it can be useful when you would like to provide the user with selection from the DataGrid items). See the code below:

HTML
<!-- Countries for selection -->
<asp:DataGrid id="countriesGrid" runat="server" 
         DataKeyField="ID" AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateColumn>
            <ItemTemplate>
                <!-- 
                Draw attention at this control. 
                We would like to use radio-buttons to
                select single country from the list.
                -->
                <asp:RadioButton id="selectRadioButton" 
                    runat="server" GroupName="country" />
            </ItemTemplate>
        </asp:TemplateColumn>
        <asp:BoundColumn DataField="Country" HeaderText="Country" 
                                  HeaderStyle-Font-Bold="True" />
        <asp:BoundColumn DataField="Capital" HeaderText="Capital" 
                                  HeaderStyle-Font-Bold="True" />
    </Columns>
</asp:DataGrid>

Now, bind to the DataGrid some data and run your ASP.NET application. Try to click at the radio buttons in the Countries list. You can select one country!... and another one... and another... Hmm-m! Didn't we really want to get this effect?

Where is a mistake? We have specified GroupName for the RadioButtons to treat them as from the single group, haven't we? Look at the piece of HTML code that has been generated from our web form. You will see something like this:

HTML
<!-- Countries for selection -->
<table cellspacing="0" rules="all" border="1" id="countriesGrid" 
                              style="border-collapse:collapse;">
    <tr>
        <td> </td>
        <td style="font-weight:bold;">Country</td>
        <td style="font-weight:bold;">Capital</td>
    </tr>
    <tr>
        <td><input id="countriesGrid__ctl2_selectRadioButton" 
             type="radio" name="countriesGrid:_ctl2:country" 
             value="selectRadioButton" /></td>
        <td>USA</td>
        <td>Washington</td>
    </tr>
    <tr>
        <td><input id="countriesGrid__ctl3_selectRadioButton" 
             type="radio" name="countriesGrid:_ctl3:country" 
             value="selectRadioButton" /></td>
        <td>Canada</td>
        <td>Ottawa</td>
    </tr>
    <!-- etc. -->

The 'name' attributes of the radio-buttons are different. Why? Here is the answer.

When rendering RadioButton control, ASP.NET uses concatenation of GroupName and UniqueID for the value of 'name' attribute. So, this attribute depends on the UniqueID of the control which depends on the owner's UniqueID etc. It is the standard solution of ASP.NET to avoid naming collisions. As the value of the 'name' attribute of the <input type="radio" /> is used for identification of postback data of the radio-button group when the from is submitting, ASP.NET developers decided to isolate radio-button groups within the bounds of the single owner control (i.e., any two radio-buttons from the same group can not have different direct owners), otherwise it can occur that you will use two third party controls that both contain radio-button groups with the same GroupName - in this case, all radio-buttons will be treated as from the single group and that will bring undesirable behavior.

Now you have understood the cause of error, but how to implement the feature we want? In the next section, I'll provide you the solution.

Solution of the problem

To solve the problem I have stated above, I've created a new GroupRadioButton web control derived from the RadioButton.

In this control, I have changed the rendering method so that 'name' attribute of the resulting HTML radio-button now depends on the GroupName only.

Another one modification is postback data handling (IPostBackDataHandler interface has been overridden).

Other functionality of the GroupRadioButton is equivalent to RadioButton.

See the source code of the GroupRadioButton for details.

Using the code

Now, let's modify the initial form. Use the following script for the Countries list:

ASP.NET
<%@ Register TagPrefix="vs" Namespace="Vladsm.Web.UI.WebControls" 
                                          Assembly="GroupRadioButton" %>
...
<!-- Countries for selection -->
<asp:DataGrid id="countriesGrid" runat="server" DataKeyField="ID" 
                                     AutoGenerateColumns="False">
    <Columns>
        <asp:TemplateColumn>
            <ItemTemplate>
                <vs:GroupRadioButton id="selectRadioButton" 
                runat="server" GroupName="country" />
            </ItemTemplate>
        </asp:TemplateColumn>
        <asp:BoundColumn DataField="Country" HeaderText="Country" 
                                  HeaderStyle-Font-Bold="True" />
        <asp:BoundColumn DataField="Capital" HeaderText="Capital" 
                                  HeaderStyle-Font-Bold="True" />
    </Columns>
</asp:DataGrid>

Add reference to the GroupRadioButton assembly, bind data for the countriesGrid, and execute this form. You will find that all radio-buttons are in the single group (i.e., user can check only one of them).

It remained only to show how to determine which of the countries have been selected:

C#
using Vladsm.Web.UI.WebControls;
...
private void selectButton_Click(object sender, System.EventArgs e)
{
    // for each grid items...
    foreach(DataGridItem dgItem in countriesGrid.Items)
    {
        // get GroupRadioButton object...
        GroupRadioButton selectRadioButton = 
            dgItem.FindControl("selectRadioButton") as GroupRadioButton;

        // if it is checked (current item is selected)...
        if(selectRadioButton != null && selectRadioButton.Checked)
        {
            // sample data that was boud to the countriesGrid
            DataTable dataSource = DataSource.CreateSampleDataSource();

            // get country corresponding to the current item...
            DataRow row = 
              dataSource.Rows.Find(countriesGrid.DataKeys[dgItem.ItemIndex]);

            // ...and show selected country information
            selectedCountryInfo.Text = 
                String.Format("Selected country: {0}, Capital: {1}", 
                row["Country"], row["Capital"]);

            return;
        }
    }

    // there are no selected countries
    selectedCountryInfo.Text = String.Empty;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralThank you! Pin
GoodQueenJen21-Aug-15 6:28
GoodQueenJen21-Aug-15 6:28 
QuestionWow! Pin
No0oshin14-Mar-15 23:42
No0oshin14-Mar-15 23:42 
QuestionAwesome Pin
Member 1017358019-Aug-13 2:40
Member 1017358019-Aug-13 2:40 
BugText Label Pin
Fabio Solariwebster25-Jan-13 13:55
Fabio Solariwebster25-Jan-13 13:55 
QuestionPlz help me Pin
soft.rajasekaran27-Dec-12 17:37
soft.rajasekaran27-Dec-12 17:37 
QuestionCSS class not present Pin
karlitr0s11-May-12 1:10
karlitr0s11-May-12 1:10 
Questionthe simplest code ..which serves the purpose Pin
Bilal Fazlani9-May-12 21:21
Bilal Fazlani9-May-12 21:21 
QuestionPossible bug? Pin
Gavin Roberts26-Nov-11 11:02
Gavin Roberts26-Nov-11 11:02 
GeneralThanks! Pin
M.AsimSiddiqui15-Jun-11 4:23
M.AsimSiddiqui15-Jun-11 4:23 
GeneralBetter implementation Pin
Martin Zarate27-Apr-11 7:49
Martin Zarate27-Apr-11 7:49 
GeneralRe: Better implementation Pin
Chris Clark23-May-11 4:31
Chris Clark23-May-11 4:31 
GeneralRe: Better implementation Pin
TrendyTim29-Nov-11 21:01
TrendyTim29-Nov-11 21:01 
Thank you Vladimir and Martin, i think Martins is slightly cleaner (less reimplemented code) so i used his modifications, however i too had the issue with the postback data not being processed so i fixed that (added
VB
Me.Attributes.Add("value", Value)
to the render method so that on postback we could tell what was selected, the full code follows.


VB
<ToolboxData("<{0}:GroupRadioButton runat=server></{0}:GroupRadioButton>")> _
Public Class GroupRadioButton
    Inherits RadioButton
    Implements IPostBackDataHandler
    Public Sub New()
        MyBase.New()
    End Sub

#Region "Properties"
     Private ReadOnly Property Value() As String
        Get
            Return UniqueID
        End Get
    End Property

#End Region

#Region "Rendering"
     Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
        Dim fixingWriter As New GroupedRadioButtonTextWriter(writer, GroupName)
        Me.Attributes.Add("value", Value)
        MyBase.Render(fixingWriter)
    End Sub

    Friend Class GroupedRadioButtonTextWriter
        Inherits HtmlTextWriter

        Private _GroupName As String

        Public Sub New(ByVal baseWriter As HtmlTextWriter, ByVal groupName As String)
            MyBase.New(baseWriter)
            _GroupName = groupName
        End Sub

        Public Overrides Sub AddAttribute(ByVal key As System.Web.UI.HtmlTextWriterAttribute, ByVal value As String)
            'do not emit any attributes in the ignore list.
            If key <> HtmlTextWriterAttribute.Name Then
                MyBase.AddAttribute(key, value)
            End If
        End Sub

        Public Overrides Sub RenderBeginTag(ByVal tagKey As System.Web.UI.HtmlTextWriterTag)
            If (tagKey = HtmlTextWriterTag.Input) Then
                ForceAddAttribute(HtmlTextWriterAttribute.Name, _GroupName)
            End If

            MyBase.RenderBeginTag(tagKey)
        End Sub

        Public Sub ForceAddAttribute(ByVal key As System.Web.UI.HtmlTextWriterAttribute, ByVal value As String)
            MyBase.AddAttribute(key, value)
        End Sub
    End Class
#End Region

#Region "IPostBackDataHandler Members"
     Private Sub IPostBackDataHandler_RaisePostDataChangedEvent() Implements IPostBackDataHandler.RaisePostDataChangedEvent
        OnCheckedChanged(EventArgs.Empty)
    End Sub

    Private Function IPostBackDataHandler_LoadPostData(ByVal postDataKey As String, ByVal postCollection As System.Collections.Specialized.NameValueCollection) As Boolean Implements IPostBackDataHandler.LoadPostData
        Dim result As Boolean = False
        Dim postValue As String = postCollection(GroupName)
        If (postValue IsNot Nothing) AndAlso (postValue = Value) Then
            If Not Checked Then
                Checked = True
                result = True
            End If
        Else
            If Checked Then
                Checked = False
            End If
        End If
        Return result
    End Function

#End Region
End Class

GeneralBetter implementation (C# Version) PinPopular
flemgrem23-Jan-12 5:02
flemgrem23-Jan-12 5:02 
GeneralAwesome ! Pin
Z_KiNGPiN23-Apr-11 21:44
Z_KiNGPiN23-Apr-11 21:44 
GeneralMy vote of 5 Pin
ccaspers4-Feb-11 10:12
ccaspers4-Feb-11 10:12 
GeneralMy vote of 5 Pin
Emeka Awagu11-Nov-10 22:55
Emeka Awagu11-Nov-10 22:55 
GeneralFantastic Pin
Member 46201357-Oct-10 5:34
Member 46201357-Oct-10 5:34 
GeneralMy vote of 5 Pin
MiroslavBraikov25-Sep-10 22:50
MiroslavBraikov25-Sep-10 22:50 
GeneralMy vote of 3 Pin
sarodgl11-Aug-10 5:46
sarodgl11-Aug-10 5:46 
GeneralMy vote of 5 Pin
Andrew Lansdowne3-Aug-10 22:56
Andrew Lansdowne3-Aug-10 22:56 
GeneralMy vote of 3 Pin
Ramanarayanan K29-Jul-10 6:44
Ramanarayanan K29-Jul-10 6:44 
GeneralYou are IT! Pin
Stevishere27-Apr-10 10:59
Stevishere27-Apr-10 10:59 
QuestionHow to add Text Property? Pin
DragothiC4-Mar-10 6:12
DragothiC4-Mar-10 6:12 
AnswerRe: How to add Text Property? Pin
Chris Clark23-May-11 4:30
Chris Clark23-May-11 4:30 
GeneralRe: How to add Text Property? Pin
Tellalca8-Sep-11 2:53
Tellalca8-Sep-11 2:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.