Radio Buttons and Repeaters in Aspx
- December 12th, 2011
- Posted in DotNet
- Write comment
If you’re using a Repeater control and have a requirement to have radio buttons in the repeated rows you may find yourself in a head scratching mess. You may find that checking one radio button does not result in all other buttons being unchecked. The radio buttons will essentially start to behave like a bunch of check boxes … not cool.
With normal html radio buttons we group them together using the ‘name’ attribute. All radio buttons with the same value in the name attribute become mutually exclusive resulting in the familiar behaviour where only one radio button in that group can be checked at any one time. In an asp:RadioButton control the name attribute maps to the GroupName parameter which normally works fine.
Things start to go astray when the radio buttons are added to a repeater however. You may be aware that asp.net will insert its own unique id for each control which is not the same as the id you originally gave it in code or markup. It does this to ensure that any elements that have the same id end up with a unique id once rendered. In the case of the repeater this is very necessary as you are taking the same elements with the same id and emitting them multiple times. Unfortunately a repeater also mangles the name attribute of the controls. Normally this can be safely ignored but radio buttons rely on this attribute to work out which group they belong to. All of a sudden each radio button belongs to its own little group and so we end up with check box behaviour.
This is a known issue explained in detail here, however, Microsoft have not yet fixed this and give no indication of if or when it will be fixed.
So now what? Well … there are a couple of work-arounds, none of which are particularly elegant.
1) Avoid using the repeater or radio buttons and see if you can solve the problem with other controls.
2) If you’re stuck with repeaters and radio buttons the most elegant solution is to use javascript to de-select other radio buttons using the click event.
This goes in the <head> tag …
//I use jquery to make life easier but you don't have to <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script> <script type="text/javascript"> function MakeRbExclusive(rb) { var rbs = $('#rbData :radio'); for (var i = 0; i < rbs.length; i++) { if (rbs[i] != rb) rbs[i].checked = false; } } </script> |
And our repeater …
<div id="rbData">
<asp:Repeater ID="repeater" runat="server">
<ItemTemplate>
<!-- I have bound to simple Dictionary<string, string> created in page load for example purposes -->
<asp:Label ID="lbl" runat="server" AssociatedControlID="radio"><%#Eval("key")%></asp:Label>
<asp:radioButton ID="radio" runat="server" value=<%#Eval("value")%> onclick="MakeRbExclusive(this);"/>
<br />
</ItemTemplate>
</asp:Repeater>
</div> |
3) Avoid the use of a repeater completely and add your controls dynamically from code behind in a loop to achieve the same result. I *really* don’t recommend this. It is finicky at best and takes very careful coding. Dynamically added controls are not automatically tracked in viewstate and can create big problems if not carefully coded. I have had to do this in the past but it is definitely an option I’d only consider once I have exhausted all others.
Happy coding!
No comments yet.