btw
btw

Reputation: 7164

Enabling and Disabling Radio Buttons Depending on User Selection

I'm looking to write jQuery to only enable radio buttons depending on which radio buttons are currently selected in accordance with some business logic.

Essentially there are 3 groups of 3 radio buttons, which end up looking something like (my apologies for being verbose with this example HTML, but hoping this will show what I mean):

<p>
  <label for="group_one">Group One</label>
</p>
<p>
  <div class="group_one">
    <div id="group_one_choice_one">
      <label for="group_one_choice_one">Choice One</label>
      <br />
      <input checked="checked" id="choice_one" type="radio" value="1" />
      <br />
    </div>
    <div id="group_one_choice_two">
      <label for="group_one_choice_two">Choice Two</label>
      <br />
      <input id="group_one_choice_two" type="radio" value="2" />
      <br />
    </div>
    <div id="group_one_choice_three">
      <label for="group_one_choice_three">Choice Three</label>
      <br />
      <input id="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_two">Group Two</label>
</p>
<p>
  <div class="group_two">
    <div id="group_two_choice_one">
      <label for="group_two_choice_one">Choice One</label>
      <br />
      <input checked="checked" id="choice_one" type="radio" value="1" />
      <br />
    </div>
    <div id="group_two_choice_two">
      <label for="group_two_choice_two">Choice Two</label>
      <br />
      <input id="group_two_choice_two" type="radio" value="2" />
      <br />
    </div>
    <div id="group_two_choice_three">
      <label for="group_two_choice_three">Choice Three</label>
      <br />
      <input id="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_three">Group Three</label>
</p>
<p>
  <div class="group_three">
    <div id="group_three_choice_one">
      <label for="group_three_choice_one">Choice One</label>
      <br />
      <input checked="checked" id="choice_one" type="radio" value="1" />
      <br />
    </div>
    <div id="group_three_choice_two">
      <label for="group_three_choice_two">Choice Two</label>
      <br />
      <input id="group_three_choice_two" type="radio" value="2" />
      <br />
    </div>
    <div id="group_three_choice_three">
      <label for="group_three_choice_three">Choice Three</label>
      <br />
      <input id="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>

Where it gets tricky is the logic needed to determine which radio buttons to display and which to enable. A user must select one choice from each group, but cannot repeat the same choice from one group to another.

Ideally when the user gets to the page, all of the radio buttons would be available but unselected.

If the user were to first select (for example) Choice Two in Group Three, the script should then disable Choice Two in both Group One and Group Two. If the user then selects Choice Three in Group Two, it should then only enable Choice One in Group One, and so on.

Any help would be very, very much appreciated. I would post the jQuery I've been attempting to write to solve this problem but I don't think I've been going about this very well and would love any help working through it. Thanks!

Upvotes: 5

Views: 13844

Answers (5)

Andy Gaskell
Andy Gaskell

Reputation: 31761

I'd skip the special classes.

$("input[type=radio]").click(function() { 
  $("input[type=radio][value=" + $(this).val() + "]").attr("disabled", "disabled"); 
  $(this).removeAttr("disabled"); 
});

Depending on your requirements you might not need the last line - it just re-enables the current radio. Your html is also missing names for your radio buttons.

Upvotes: 8

karim79
karim79

Reputation: 342765

Done & tested, here's the jQuery:

$(document).ready(function() {
    $('input:radio').click(function() {
       //reset all the radios
       $('input:radio').removeAttr('disabled');
       if($(this).is(':checked')) {
           var val = $(this).val();
           //disable all the ones with the same value
           $('input:radio').each(function() {
               if(val == $(this).val()) {
                   $(this).attr('disabled',true);
               }
           });
           //let's not disable the one we have just clicked on
           $(this).removeAttr('disabled');
       }
    });
});

and the modded markup:

<p>
  <label for="group_one">Group One</label>
</p>
<p>
  <div class="group_one">
    <div>
      <label for="group_one_choice_one">Choice One</label>
      <br />
      <input checked="checked" name="group_one" type="radio" value="1" />
      <br />
    </div>
    <div>
      <label for="group_one_choice_two">Choice Two</label>
      <br />
      <input name="group_one" type="radio" value="2" />
      <br />
    </div>
    <div>
      <label for="group_one_choice_three">Choice Three</label>
      <br />
      <input name="group_one" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_two">Group Two</label>
</p>
<p>
  <div class="group_two">
    <div>
      <label for="group_two_choice_one">Choice One</label>
      <br />
      <input checked="checked"  name="group_two"  type="radio" value="1" />
      <br />
    </div>
    <div>
      <label for="group_two_choice_two">Choice Two</label>
      <br />
      <input name="group_two" type="radio" value="2" />
      <br />
    </div>
    <div>
      <label for="group_two_choice_three">Choice Three</label>
      <br />
      <input name="group_two" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>
<p>
  <label for="group_three">Group Three</label>
</p>
<p>
  <div class="group_three">
    <div>
      <label for="group_three_choice_one">Choice One</label>
      <br />
      <input checked="checked" name="group_three" type="radio" value="1" />
      <br />
    </div>
    <div>
      <label for="group_three_choice_two">Choice Two</label>
      <br />
      <input name="group_three" type="radio" value="2" />
      <br />
    </div>
    <div>
      <label for="group_three_choice_three">Choice Three</label>
      <br />
      <input name="choice_three" type="radio" value="3"/ >
      <br />
    </div>
  </div>
</p>

Changes to the markup:

  • Got rid of the inner DIV IDs.
  • Changed the ID attributes of the radios to NAME, so they behave like radio buttons.

Upvotes: 3

JJ Geewax
JJ Geewax

Reputation: 10579

You might be able to use something like (I haven't tested this, it's just to get the ball rolling...)

The idea is: whenever you click on a radio, disable all the radios in all the groups with that value, except the one that was just clicked.

$(document).ready(function() {
    $("input[type=radio]").click(function() {
        var val = $(this).val();
        var $all_radios = $("input[type=radio]").filter("[value=" + val + "]");
        $all_radios.not($(this)).attr('disabled', 'disabled');
        return true;
    });
});

Upvotes: 3

Zed
Zed

Reputation: 57678

If you add speial classes to same choices, e.g. class="choice_one", and then in your event handler you can:

if ($this).hasClass("choice_one") { $(".choice_one").attr("disabled", "disabled"); }
else if ($this).hasClass("choice_two") { ... }
...

Upvotes: 1

Mutation Person
Mutation Person

Reputation: 30520

Firstly, you really shoudln't have duplicate ids in your code.

I would make all the IDs unique, and then give your radioboxes a class name - class="choice_three" for example.

You can give your divs an id, selecting by an id is faster than class, so id="group_three" for example.

Then to select a radio button, simply use the following code:

$("#group_three .choice_three").attr("disabled", "disabled");

Note, the space between #group_three and .choice_three is important.

Or even faster:

$("#group_three input:radio.choice_three").attr("disabled", "disabled");

Another thing to note as well, the label "for" should be for the radio button, not the div.

Upvotes: 2

Related Questions