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!