0

I need either:

  • Radio buttons that can be deselected OR
  • Mutually exclusive checkboxes

Background info:

I have a repeater.

For each row in the repeater there is an associated document that can be either "Generated" or "Reprinted".

The user should be able to select up to one checkbox in any given row. After this, one button click will handle all of their selections in one pass.

When I search for "Mutually exclusive checkboxes", the common response is, "This is what radio buttons are for."

When I search for "Deselectable radio buttons", the common response is, "This is what check boxes are for."

Others have suggested custom JavaScript/ jQuery solutions but none in which the number of CheckBoxes/RadioButtons and their IDs are variable.

I find it hard to believe that this functionality isn't supported by ASP.NET controls. Has anyone faced this problem? Is there another control I could use or does this require a custom solution?

NOTE: The only third party software I have access to is Telerik's UI for ASP.NET AJAX, which doesn't contain an obvious solution.

jcmcmaster
  • 27
  • 2
  • 6
  • what do you mean by "deselected" ? you can set all the radios in a group to `.checked=false` – dandavis Jun 21 '16 at 18:42
  • The user should be able to remove a selection from a radio button, as they would be able to do with a checkbox. So you're suggesting a "clear selections" button in each row that calls ".checked=false" on a group of radio buttons? – jcmcmaster Jun 21 '16 at 18:49
  • As far as I know there isn't an accessible "OnClientClicked" handler for ASP:RadioButtons so there would need to be another control, right? – jcmcmaster Jun 21 '16 at 18:50
  • If you have some set of checkboxes, you can control which are and are not checked through some set of events. If one is checked, uncheck the other, etc. – pay Jun 21 '16 at 18:50
  • 2
    The concept of deselectable radio buttons is broken. Radio buttons are a UI metaphor for "one value is valid at any time". If "unselected" (a.k.a. "undefined") is one of the values you have, make a radio button for it. – Tomalak Jun 21 '16 at 18:51
  • You can implement "Mutually exclusive checkboxes" in 5 to 7 lines using JS or less using jquery. – Alex Kudryashev Jun 21 '16 at 18:54
  • @Alex Not everything that is technically possible should be done. – Tomalak Jun 21 '16 at 19:08
  • This was my initial thought, @Alex Kudryashev. However, since these checkboxes will be repeated in a repeater, how do I ensure that I'm toggling ONLY that checkbox's counterpart? How can I associate 2 checkboxes in a repeater row? They don't have group names like RadioButtons. When one is clicked, by what mechanism can I find the Client ID of the other one? By digging into the repeater row? – jcmcmaster Jun 21 '16 at 19:13
  • Why not use @Tomalak's suggestion then? – ConnorsFan Jun 21 '16 at 19:23
  • A "do-nothing" option feels bloated. Even if I had room for a 3rd radio button, I'd rather just allow the user to uncheck a selection. – jcmcmaster Jun 21 '16 at 19:33
  • 2
    It's not about what you perceive as bloated. It's about usability, and that is based on convention and obviousness. It's neither obvious that a radiobutton is deselectable nor is it a convention a typical user knows. It goes against how radiobuttons work, breaking user expectations for the mere sake of your gut feeling. I wouldn't say that's a good reason to do that. It's like using a dropdown for two entries, "Yes" and "No". Just wrong. – Tomalak Jun 21 '16 at 19:49
  • A third alternative would be a DropDownList with the "undefined" option. – ConnorsFan Jun 21 '16 at 19:51
  • "Deselectible" radio buttons also can be implemented in JS. Just remember last value of the group and unselect on the 2nd click on the same button. – Alex Kudryashev Jun 21 '16 at 20:44

3 Answers3

2

Sample "Mutually exclusive checkboxes" in a repeater using Javascript:

window.onload = function(){
   var repeater = document.getElementById('repeater');
   var chks = repeater.querySelectorAll('[type=checkbox]');
   for(var i = 0,chk;chk = chks[i];++i){
      chk.onclick = function(){
         if(this.checked){
           for(var j=0,ch;ch=chks[j;++j]){
             if(ch !== this)
                ch.checked = false;
           }//for
         }//if(this...
      }//chk.onclick
   }//for(var i
}//window.onload
Alex Kudryashev
  • 9,120
  • 3
  • 27
  • 36
1

use a checkboxlist and handle the SelectedIndexChanged

private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)  
{  
    if (checkedListBox1.CheckedItems.Count > 0)  
    {  
        foreach (int i in checkedListBox1.CheckedIndices)  
        {  
            checkedListBox1.SetItemCheckState(i, CheckState.Unchecked);  
        }  
    }  
} 
Paul Swetz
  • 2,234
  • 1
  • 11
  • 28
0

I'm more of a StackOverflow guy, but I eventually found this on GitHub.

https://gist.github.com/kikegarcia/6104607

And here's what I ended up with, along with some documentation. Basically the same thing, but using .prop instead of .attr since reading Tim Down's explanation of the difference between the two here: .prop() vs .attr()

// mutually exclusive checkboxes within the scope of a repeater row
function cbOnClick(sender) {   
  if (sender.checked)                                                      
    $(sender).siblings(":checkbox").prop("checked", false);
    //  1        2          3         4      5        6
}
  1. Get the event-initiating checkbox as a jQuery object.
  2. Get the sibling elements of our checkbox...

  3. ... with type = "checkbox".

  4. Access their properties...

  5. ... of type "checked"...
  6. ... and set them to false. => Automatic unchecking of sibling checkboxes.
Community
  • 1
  • 1
jcmcmaster
  • 27
  • 2
  • 6