Radio Buttons with 2-Way Exclusivity



Let's say you were tasked with creating a UI in which users can rate three candy bars from their most to least favorite. A grid of radio buttons isn't a terrible way to go about this.


The good news is that radio buttons have natural exclusivity in the name-group they are in, and we can use that to our advantage. The bad news is that we have interlocking groups and there is no way to express that in a functional way through HTML alone.



Let's craft the HTML in such a way that the horizontal groups share the same name, granting exclusivity automatically. And we'll also add an HTML data-* attribute which signifies the column which we'll use to simulate the vertical exclusivity with JavaScript1.

<table> <tr> <th></th> <th>1</th> <th>2</th> <th>3</th> </tr> <tr> <td>Twix</td> <td><input type="radio" name="row-1" data-col="1"></td> <td><input type="radio" name="row-1" data-col="2"></td> <td><input type="radio" name="row-1" data-col="3"></td> </tr> <tr> <td>Snickers</td> <td><input type="radio" name="row-2" data-col="1"></td> <td><input type="radio" name="row-2" data-col="2"></td> <td><input type="radio" name="row-2" data-col="3"></td> </tr> <tr> <td>Butterfingers</td> <td><input type="radio" name="row-3" data-col="1"></td> <td><input type="radio" name="row-3" data-col="2"></td> <td><input type="radio" name="row-3" data-col="3"></td> </tr> </table>


Our incredibly simple design can be accomplished with this CSS:


table { border-collapse: collapse; } td, th { border: 1px solid #ccc; padding: 10px; } th:empty { border: 0; }


I wouldn't have even posted that CSS except I think it's a super useful case of the :emptypseudo class selector.

Now to grant the vertical group exclusivity, we'll use a touch of jQuery:

var col, el;
$("input[type=radio]").click(function() { el = $(this); col = el.data("col"); $("input[data-col=" + col + "]").prop("checked", false); el.prop("checked", true); });

When a radio button is clicked, the column is determined and all other radio buttons in that column are turned off, then the clicked on is turned back on.
That's all there is to it.

Comments