Search code examples
javascriptjqueryformstwitter-bootstrapradio-button

Uncheck bootstrap radio button


I'm trying to uncheck a radio button wrapped with a label in a button group like this:

<div>
            <label class="btn btn-primary">
              <input type="radio" name="radio1" class="radio1" />
    Radio1
            </label>
</div>
<div>
            <label class="btn btn-primary">
              <input type="radio" name="radio2" class="radio2" />
    Radio2
            </label>
</div>
$('.btn').on('click', function(e) {
      // Check if another option was previously checked
      if ($(this).parent().parent().find(':radio:checked').length == 1) {
        inner_input = $(this).find('input');
        if (inner_input.prop('checked')) {
          e.stopImmediatePropagation();
          e.preventDefault();
          inner_input.prop('checked', false);
          $(this).removeClass('active');
        }
});

Unfortunately it doesn't work and the label is still active even after the second click.


Solution

  • Why this happens?

    Let's first see what are click, mouseup and mousedown events :

    mousedown

    Fires when the user depresses the mouse button.

    mouseup

    Fires when the user releases the mouse button.

    click

    Fires when a mousedown and mouseup event occur on the same element. Fires when the user activates the element that has the keyboard focus (usually by pressing Enter or the space bar).

    So When using click event, the radio button is checked, it means that radio.is(':checked') will always return true unless you disable default behavior. So you can do what you want in 2 ways :


    1- With Mouseup event, in this case you can determine the state of radio button wether it's checked or not.But in this way you need one little extra code to disable the default behvaior of click event

    $('label').on('mouseup', function(e){
        var radio = $(this).find('input[type=radio]');
    
      if( radio.is(':checked') ){
        radio.prop('checked', false);
    
      } else {
        radio.prop('checked', true);
    
      }
    
    });
    
    // Disable default behavior
    $('label').click(function(e){
        e.preventDefault();
    });
    

    Fiddle


    And 2 , You can wrap it all together, disable click's default behavior and do the rest in one event:

    $('label').click(function(e) {
        e.preventDefault();
    
        var radio = $(this).find('input[type=radio]');
    
        if (radio.is(':checked')) {
            radio.prop('checked', false);
    
        } else {
            radio.prop('checked', true);
    
        }
    });
    

    Fiddle

    I did answer this question using 2 different events with a purpose, sometimes in more complex problems you may be forced to use the mouseup event instead of click