views:

6205

answers:

7

I got a templated control (a repeater) listing some text and other markup. Each item has a radiobutton associated with it, making it possible for the user to select ONE of the items created by the repeater.

The repeater writes the radiobutton setting its id and name generated with the default asp.net naming convention making each radiobutton a full 'group'. This means all radiobuttons are independant on each other, which again unfortunately means i can select all radiobuttons at the same time. The radiobutton has the clever attribute 'groupname' used to set a common name so they get grouped together and thus should be dependant (so i can only select one at a time). The problem is - this doesn't work - the repeater makes sure the id and thus the name (which controls the grouping) are different.

Since i use a repeater (could have been a listview or any other templated databound control) i can't use the RadioButtonList. So where does that leave me?

I know i've had this problem before and solved it. I know almost every asp.net programmer must have had it too, so why can't i google and find a solid solution to the problem? I came across solutions to enforce the grouping by javascript (ugly!) or even to handle the radiobuttons as non-server controls, forcing me to do a Request.Form[name] to read the status. I also tried experimenting with overriding the name attribute on the PreRender event - unfortunately the owning page and masterpage again overrides this name to reflect the full id/name so i end up with the same wrong result.

If you have no better solution than i posted, you are still very welcome to post your thoughts - atleast i'll know that my friend 'jack' is right about how messed up 'asp.net' is sometimes ;)

+5  A: 

asp.net radiobutton repeater problem

Indeed an unfortunate consequence of the id mangling. My take would be creating a - or picking one of the many available - custom control that adds support for same name on the client.

Cristian Libardo
Unfortunately you are right, but it's such a pain!
Per Hornshøj-Schierbeck
+1  A: 

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q316495

That is just plain insane... It's a bug since 1.0 framework and it has such a big impact. I need to inherit the radiobutton and override a couple methods to make it work (for my current asp.net version) what gives?

Per Hornshøj-Schierbeck
+3  A: 

ASP.NET Tip: Using RadioButton Controls in a Repeater

This is the code for the JavaScript function:

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;
}

The code is linked to the Repeater through the ItemDataBound event. For it to work properly, you need to know the name of the Repeater control, as well as the GroupName you're assigning to the RadioButtons. In this case, I'm using rptPortfolios as the name of the Repeater, and Portfolios as the group name:

protected void rptPortfolios_ItemDataBound(object sender,
                                           RepeaterItemEventArgs e)
{
   if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType
      != ListItemType.AlternatingItem)
      return;

   RadioButton rdo = (RadioButton)e.Item.FindControl("rdoSelected");
   string script =
      "SetUniqueRadioButton('rptPortfolios.*Portfolios',this)";
   rdo.Attributes.Add("onclick", script);

}

REF: http://www.codeguru.com/csharp/csharp/cs_controls/custom/article.php/c12371/

+1  A: 

Vladimir Smirnov has already created a great custom control that resolves this issue. We have been using the GroupRadioButton in our projects and it has been working perfectly with radio buttons created inside of a repeater and others outside the repeater all being a part of the same group.

ObligatoryMoniker
A: 

This may not be the ideal solution for everyone, but I did the following using jQuery.

<asp:RadioButton ID="rbtnButton1" groupName="Group1" runat="server" /> <asp:RadioButton ID="rbtnButton2" groupName="Group1" runat="server" />

etc...

Then include the following code in your master page. (or all your pages)

$(function() {
//This is a workaround for Microsoft's GroupName bug.  
//Set the radio button's groupName attribute to make it work.
$('span[groupName] > input').click(function() {
    var element = this;
    var span = $(element).parent();
    if (element.checked) {
        var groupName = $(span).attr('groupName');
        var inputs = $('span[groupName=' + groupName + '] > input')
        inputs.each(function() {
            if (element != this)
                this.checked = false;
        });
    }
});

});

helios456
A: 

This might be a little better..

I have a usercontrol which is essentially a set of radiobuttons inside a repeater, each instance of the usercontrol has a public property called FilterTitle, which is unique per instance.

add these two properties to your radiobutton replacing FilterTitle with your own public property name

onclick='<%# "$(\"input[name$=btngroup_" + FilterTitle + "]\").removeAttr(\"checked\"); $(this).attr(\"checked\",\"checked\");" %>' GroupName='<%# "btngroup_" + FilterTitle  %>'

more simply..

onclick="$('input[name$=btngroup1]').removeAttr('checked'); $(this).attr('checked','checked');" GroupName="btngroup1"
tbilly
A: 

I use jQuery script:

<script type="text/javascript">
    function norm_radio_name() {
        $("[type=radio]").each(function (i) {
            var name = $(this).attr("name");
            var splitted = name.split("$");
            $(this).attr("name", splitted[splitted.length - 1]);
        });
    };

    $(document).ready(function () {
        norm_radio_name();
    });

    // for UpdatePannel
    var prm = Sys.WebForms.PageRequestManager.getInstance();

    prm.add_endRequest(function () {
        norm_radio_name();
    });
</script>
Andrey Ilnitskiy