iFinity Blogs 

Simple fix for Radio Button controls in an ASP.NET Repeater using jQuery

Apr 13

Written by:
Tuesday, April 13, 2010 9:26 AM  RssIcon

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:

aspnet_radio_buttons_repeater

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

Tags:
Categories:
Location: Blogs Parent Separator Crafty Code

6 comment(s) so far...


Gravatar

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
Gravatar

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
Gravatar

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
Gravatar

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
Gravatar

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
Gravatar

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

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Add Comment   Cancel 
Bruce Chapman
Hi, I'm Bruce Chapman, and this is my blog. You'll find lots of information here - my thoughts about business and the internet, technical information, things I'm working on and the odd strange post or two.

 

Share this
Get more!
Subscribe to the Mailing List
Email Address:
First Name:
Last Name:
You will be sent a confirmation upon subscription

 

Follow me on Twitter
Stack Exchange
profile for Bruce Chapman at Stack Overflow, Q&A for professional and enthusiast programmers
Klout Profile