Bootstrap Radio Buttons with ASP.NET Web Forms and UpdatePanels
(Update 2015/07/07: Debugged and cleaned up code snippets and attached sample Visual Studio project.)
Let’s say I am taking a WebForms site and updating it to make it look nicer. Ideally I would update the project to ASP.NET MVC, but let’s say that won’t be possible.
As part of my site, I have
<asp:RadioButton runat="server" id="radioA1" GroupName="radioA" AutoPostBack="True"/> <label for="radioA1">Option 1</label> <br/> <asp:RadioButton runat="server" id="radioA2" GroupName="radioA" AutoPostBack="True"/> <label for="radioA2">Option 2</label>
Now, to make those radio buttons look nicer, I wrap them up like so, using Bootstrap’s CSS rules:
<div class="btn-group" data-toggle="buttons"> <label class="btn btn-default"> <asp:RadioButton runat="server" id="radioB1" GroupName="radioB" AutoPostBack="True"/> Option 1 </label> <label class="btn btn-default"> <asp:RadioButton runat="server" id="radioB2" GroupName="radioB" AutoPostBack="True"/> Option 2 </label> </div>
Immediately, there is a problem. Although the radio buttons will switch the active state as intended, they do not post back. Due to the AutoPostBack=”True” attribute, ASP.NET generates a click event on each radio button, which goes out via AJAX and results in a partial postback. However, the label wrapping around the radio button is preventing the click event from being fired.
I played around with changes to the code and finally landed on a solution. First, I added runat=”server” and an id to each of the labels, because they will be modified in the codebehind page.
<div class="btn-group" data-toggle="buttons"> <label runat="server" id="lbl_radioC1" class="btn btn-default"> <asp:RadioButton runat="server" id="radioC1" GroupName="radioC" AutoPostBack="True"/> Option 1 </label> <label runat="server" id="lbl_radioC2" class="btn btn-default"> <asp:RadioButton runat="server" id="radioC2" GroupName="radioC" AutoPostBack="True"/> Option 2 </label> </div>
Now, in the codebehind, I created a list of all the pairs of label and radio button that need to trigger postbacks:
protected void Page_Load(object sender, EventArgs e) { List<Tuple<RadioButton, HtmlGenericControl>> listRadio = new List<Tuple<RadioButton, HtmlGenericControl>>(); listRadio.Add(new Tuple<RadioButton, HtmlGenericControl>(radioC1, lbl_radioC1)); listRadio.Add(new Tuple<RadioButton, HtmlGenericControl>(radioC2, lbl_radioC2)); }
Finally, for each pair, I did the following steps:
- Assign the same onclick action on the label that is assigned to the radio button. This way, clicking the label will trigger the same postback that was previously triggered by clicking the radio button.
- Make sure the active class is assigned to the selected radio button option.
The code I used looked like this:
foreach (Tuple<RadioButton, HtmlGenericControl> objPair in listRadio) { objPair.Item2.Attributes["class"] = "btn btn-default " + (objPair.Item1.Checked ? " active" : ""); objPair.Item2.Attributes["onclick"] = "javascript:setTimeout('__doPostBack(\\'" + objPair.Item1.ClientID + "\\',\\'\\')', 0);"; }
Finally, the styled radio buttons were posting back, and in testing worked in all browsers I had available. There may be more elegant ways to solve this problem, but this one worked for me. After multiple failed attempts at solving the problem, I’m happy with an inelegant solution if it works.
Download a sample Visual Studio 2010 C# WebForms project here: BootstrapDataToggleTest. (Click Download zip to get the entire project.)
Hi,
I have been looking for this answer.
Could you put the whole code please…I can’t get this to work.
Sorry, I had some errors in the code samples. I fixed these and also uploaded a sample project. Good luck – I hope you get your problem solved!
It’s not working…
could you share your code
Thank you for the prompt reply. I found a work around. But I’ll keep your code since my workaround will end up having lot of repeats rather than just a loop.
Here’s my work around.
aspx:
.Cs file (no extra reference library needed)
protected void rdoAdCategoryFurnitures_CheckedChanged(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine(“rdoAdCategoryFurnitures”);
lblTest1.Attributes[“class”] = “btn btn-default active”;
lblTest2.Attributes[“class”] = “btn btn-default”;
}
protected void rdoAdCategoryRealEstates_CheckedChanged(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine(“rdoAdCategoryRealEstates_CheckedChanged”);
lblTest2.Attributes[“class”] = “btn btn-default active”;
lblTest1.Attributes[“class”] = “btn btn-default”;
}
Add this to your aspx label (hope this time your script injection won’t block it)
aspx label add these where you can just change your radio button id in the doPostBAck function:
runat=”server” id=”lblTest1″ class=”btn btn-default” onclick=”javascript:setTimeout(‘__doPostBack(\’ctl00$MainContent$rdoAdCategoryFurnitures\’,\’\’)’, 0)”
Many thanks for your help with this!
This worked great for single RadioButton usage, but is there also a solution for when we have to use a RadioButtonList with AutoPostback?
Thanks
Good post, but you can also convert them into switch buttons like in iOS
Creating bootstrap switch button (Easy way) which looks better UI.
Thanks