Having RadioButtons on a Repeater or DataList

Repeaters are very powerful controls that allows us to present formated information from a datasource.

Recently I needed to include some RadioButtons inside a Repeater so I could select one of the items from the repeater, but to my surprise, and old bug resurfaced. Reference to the bug can be found here but I will include some information regarding it:

SYMPTOMS

When you add a ASP.NET RadioButton control to the ItemTemplate of a data-bound Repeater server control, the RadioButton control that you created is not mutually exclusive when you run the ASP.NET page. This problem occurs even if the GroupName attribute is set for the RadioButton controls.

CAUSE

This problem occurs because the Repeater server control implements the INamingContainer interface, which requires that all controls that are nested within it must have a unique name when rendered in Hypertext Markup Language (HTML). Therefore, the HTML name attribute of any rendered child server control is unique.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

Well, the products in cuestion are:

  • Microsoft ASP.NET 1.0
  • Microsoft ASP.NET 1.1

But guess what, it happens also in ASP.NET 2.0/3.0/3.5, so someone forgot to fix this thing.

Anyway, I found this very helpful article from Erick Smith at CodeGuru.com that helps overcome this problem. The solution is a JavaScript function that will be attached to every RadioButton as it is being bounded in the Repeater. The function is:

function SetUniqueRadioButton(nameregex, current)
{
      re =
new RegExp(nameregex);
     
for(i = 0; i < document.forms[0].elements.length; i++)
      
{
            elm = document.forms[0].elements[i]
            
if (elm.type == 'radio')
            {
                 
if (re.test(elm.name))
                  {
                          elm.checked =
false;
                  }
             }
      }
      current.checked =
true;
}

That you must add to your page on the HEAD section. Then link the function to the RadioButtons in the OnItemDataBound event for the Repeater. NOTE that you must know the Repeater name and the GroupName for the RadioButtons. For this example, the name of the Repeater is "Repeater1" and the name of the RadioButtons GroupName property is "RadioGroup".

And that's it. You will end up with a bunch of RadioButtons all with the same GroupName and working as expected.

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
     
if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return;
     
RadioButton rb = (RadioButton) e.Item.FindControl("RadioButton");
      string script = "SetUniqueRadioButton('Repeater1.*RadioGroup',this)";
      rb.Attributes.Add(
"onclick", script);
}

But you know what, this can also be applied for DataList controls. In the source code that I've included I have a page with a Repeater and a DataList so you can see that it's exactly the same form of solution.

Hope you like it. Enjoy!

 

11 Comments

  • Nice implementation for the DataGrid Control.

    Thanks Ben.

  • What if there are multiple Columns of radio button

  • @kamii47

    Well, it's pretty much the same thing. You set a different GroupName for different columns and attach the javascript function to the radio buttons.

    For example, if you have a second column with radio buttons, and you name the group "SecondGroup" (on the same Repeater) and the RadioButton is called "RadioButton2", you would only have to modify the ItemDataBound event like this:

    protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
    if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return;
    RadioButton rb = (RadioButton) e.Item.FindControl("RadioButton");
    string script = "SetUniqueRadioButton('Repeater1.*RadioGroup',this)";
    rb.Attributes.Add("onclick", script);

    rb = (RadioButton) e.Item.FindControl("RadioButton2");
    string script = "SetUniqueRadioButton('Repeater1.*SecondGroup',this)";
    rb.Attributes.Add("onclick", script);

    }


    Hope this will help you.

  • Jose Rolando Guay Paz:
    >>> Nice implementation for the DataGrid Control.

    This particular web control (at CodeProject) can actually be used with or without the DataGrid control. The example just happens to demonstrate this with a DataGrid.

  • A small optimization

    function SetUniqueRadioButton(nameregex, current)
    {
    re = new RegExp(nameregex);
    var repeaterElements=document.getElementById('').getElementsByTagName('input');
    for(i = 0; i < repeaterElements.length; i++)
    {
    elm = repeaterElements[i]
    if (elm.type == 'radio')
    {
    if (re.test(elm.name))
    {
    elm.checked = false;
    }
    }
    }
    current.checked = true;
    }

    thanks for the code

  • the script do not work good in ie 8 why?

  • we're almost on version 4 and we still can't do radio buttons correctly. you can see why most web developers use php can't you *rolls eyes*

  • Para mim não funcionou a função js

  • This is exactly the solution which I looking for. Thanks , this is great!

  • the script is not working in IE8, please give a solution....

  • Be smart, use a dropdownlist ! :P

Comments have been disabled for this content.