Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
Apr
13
Written by:
Tuesday, April 13, 2010 9:26 AM
I’ve come across this problem a few times, and have usually just worked my way around it.
The problem is when you want to create a list of Radio Buttons to display on a page, and you need to show these with other data, using an ASP.NET repeater (or DataList, or DataGrid).
Here’s what your code might look like:
<asp:Repeater id=”rptValues” runat=”server”>
<ItemTemplate>
<div>
<asp:Label id=”lblValue” runat=”server” Text=”Value” />
<asp:RadioButton id=”optValue” runat=”server” Name=”options” />
<asp:TextBox id=”txtValue” runat=”server” />
</div>
</ItemTemplate>
</asp:Repeater>
If you run a DataBind to show values for this repeater, the Html will end up something like this:
<div>
<span id="rptValues_ctl01_lblValue">One</span>
<input id="rptValues_ctl01_optValue" type="radio" value="optValue"
name="rptValues$ctl01$options" />
<input id="rptValues_ctl01_txtValue" type="text" value="One"
name="rptValues$ctl01$txtValue" />
</div>
<div>
<span id="rptValues_ctl02_lblValue">Two</span>
<input id="rptValues_ctl02_optValue" type="radio" value="optValue"
name="rptValues$ctl02$options" />
<input id="rptValeus_ctl02_txtValue" type="text" value="Two"
name="rptValues$ctl02$txtValue" />
</div>
(Note I haven’t shown the ‘code behind’ here, just take it that I have bound to a string list which consists of ‘one’ and ‘two’)
Because the two ‘radio’ inputs have a different ‘name’ attribute, then they will act independently of each other, and you’ll be able to select all of them in the page. The ASP.NET databinding code does this as a standard manner of treating the ‘name’ attribute. Here’s what the above Html will display:
Note that both of the options are selected : most users would be completely flummoxed by that one and be frantically clicking back, undo, searching for the ‘help’ button or probably even restarting their computer thinking it was their fault. None of these actions are what you want to encourage.
You can’t fix this by changing the name value in the code-behind, it’s a bug/feature of ASP.NET. Trust me, I’ve done the research and legwork on this one for you. You’ll find some nasty fixes floating around on MSDN sites, but they often don’t work or are very fiddly, inefficient and fragile.
In the past I have laboured around this by using different input structures and types, but it occurred to me that jQuery offers the simplest, most elegant solution in a couple of lines:
jQuery("[name$='$optValue']").attr("name",jQuery("[name$='$optValue']").attr("name"));
jQuery("[name$='$optValue]").click(function (){
//set name for all to name of clicked
jQuery("[name$='$optValue]").attr("name", this.attr("name"));
});
Of course, this assumes that you have the jQuery library already reference for the page. I’ve used the long-form notation of jQuery instead of $() – it makes no difference. What the first line does is select all of the inputs on the page which end with ‘optValue’ – which is all the ‘optValue’ items in the ASP.NET repeater. It then changes the ‘name’ attribute to first value found for all the ‘optValue’ elements. The attr(“name”) function (used here in ‘get’ format) always returns the first in the list. So all the option buttons get the same ‘name’ attribute in the Html, which allows the select to work correctly.
If you just need this to work like a radio button, that’s all you need to do. However, if you need to read the selection value in some postback-linked code, the optValue.Checked value will always equal ‘true’ for the first value, and ‘false’ for the others, regardless of which item in the list is actually selected. This is related to the way that ASP.NET does the viewstate calculations to preserve the values of the page controls. Whichever item in the option control group has a name which matches the id value will be selected as true. This is a problem, but it’s possible to use this strange feature to work for you instead of against you.
The second line (or block if you like) attaches a jQuery click event handler to the option button. What this does is set the name attribute of all of the selected option buttons, the same as the initial line of code does. However, in this case, it sets the name attribute to the value of the clicked item. Because ASP.NET uses the match between the ID value and the name attribute to determine if an item is checked, this means you can check the value of optValue.Checked, and it will be true for the correct item.
To use this script, just include it either in a javascript include, or just insert it directly into the page between <script> elements.
Once that is done, all the option input controls belong to the same group, and you’ll only be able to select one at a time, just the way it should be.
Copyright ©2010 Bruce Chapman
6 comment(s) so far...
Re: Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
Bruce,
Simple fix for something that shouldn't be happening in the first place. Great catch.
By Pavlicko on
Monday, August 23, 2010 8:38 AM
|
Re: Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
Bruce,
I found your fix a little late, but in my trials I found that altering the name attribute would stop my server side code from being able to see the value. The fix I came up with to overcome this was to set a change event listener on all my radiobuttons in the datalist. Then when one of them was selected, I'd just deselect all the others. Here's the code (note rbCause is the ID of my radiobutton tag).
$(document).ready(function() { $('input[id*=rbCause]').change( function() { var rbid = $(this).attr('id'); //when an item changes unselect all the others $('input[id*=rbCause]').each( function() { if($(this).attr('id') != rbid) $(this).attr('checked',false); }); }); });
By Paul on
Friday, November 12, 2010 4:41 PM
|
Re: Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
Can't you just set the GroupName property to have all radios in the same GroupName act as expected ?.
By Tim on
Tuesday, November 29, 2011 3:43 PM
|
Re: Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
Having actually just gone to test the code i see the bug in MS's implementation of the radio (i cant believe they didnt fix it).
I just implemented a modified version of this this as the solution. www.codeproject.com/KB/webforms/How_group_RButtons.aspx
By Tim on
Wednesday, November 30, 2011 5:52 PM
|
Re: Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
@tim - that's effectively what code does. You can't set it code behind because the repeater control doesn't allow you to do that.
By Bruce Chapman on
Tuesday, November 29, 2011 3:47 PM
|
Re: Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery
I should point out that I have changed this original solution to this updated version: jQuery("[name$='$optValue']").attr("name",jQuery("[name$='$optValue']").attr("name")); jQuery("[name$='$optValue']").click(function (event){ //set name for all to name of clicked var clickedName = event.currentTarget.id.replaceAll('_','$'); jQuery("[name$='$optValue']").attr("name", clickedName); });
This change fixes a bug by getting the name of the event target instead.
By Bruce Chapman on
Monday, August 23, 2010 10:31 AM
|