[javascript] jQuery check/uncheck radio button onclick

I have this code to check/uncheck a radio button onclick.

I know it is not good for the UI, but I need this.

$('#radioinstant').click(function() {     
  var checked = $(this).attr('checked', true);
  if(checked){ 
    $(this).attr('checked', false);
  }
  else{ 
    $(this).attr('checked', true);
  }
});

The above function is not working.

If I click on the button, nothing changes. It remain checked. Why? Where is the error? I am not a jQuery expert. I am on jQuery 1.3.2

Just to be clear #radioinstant is the ID of the radio button.

This question is related to javascript jquery radio

The answer is


I took https://stackoverflow.com/a/13575528/80353 and adapted it like this

$(document).ready(function() {

        $('body').on('click', 'input[type="radio"]', function() {
            changeCheckedAttributes($(this));
        });
        function changeCheckedAttributes(elt) {
            $("input[name='"+$(elt).attr("name")+"']:radio").not($(elt)).removeData("chk");
            $("input[name='"+$(elt).attr("name")+"']:radio").not($(elt)).removeAttr("checked");
            $("input[name='"+$(elt).attr("name")+"']:radio").not($(elt)).prop("checked", false);
            $(elt).data("chk",!$(elt).data("chk"));
            $(elt).prop("checked", true);
            $(elt).attr("checked", $(elt).data("chk"));
        }

    });

The solutions I tried from this question did not work for me. Of the answers that worked partially, I still found that I had to click the previously unchecked radio button twice just to get it checked again. I'm currently using jQuery 3+.

After messing around with trying to get this to work using data attributes or other attributes, I finally figured out the solution by using a class instead.

For your checked radio input, give it the class checked e.g.:

<input type="radio" name="likes_cats" value="Meow" class="checked" checked>

Here is the jQuery:

$('input[type="radio"]').click(function() {
    var name = $(this).attr('name');

    if ($(this).hasClass('checked')) {
        $(this).prop('checked', false);
        $(this).removeClass('checked');
    }
    else {
        $('input[name="'+name+'"]').removeClass('checked');
        $(this).addClass('checked');
    }
});

I have expanded on the previous suggestions. This works for me, with multiple radios coupled by the same name.

$("input[type='radio']").click(function()
{
  var previousValue = $(this).attr('previousValue');
  var name = $(this).attr('name');

  if (previousValue == 'checked')
  {
    $(this).removeAttr('checked');
    $(this).attr('previousValue', false);
  }
  else
  {
    $("input[name="+name+"]:radio").attr('previousValue', false);
    $(this).attr('previousValue', 'checked');
  }
});

_x000D_
_x000D_
        $(document).on("click", "input[type='radio']", function(e) {_x000D_
            var checked = $(this).attr("checked");_x000D_
            if(!checked){_x000D_
                $(this).attr("checked", true);_x000D_
            } else {_x000D_
                $(this).removeAttr("checked");_x000D_
                $(this).prop("checked", false);_x000D_
            }_x000D_
        });
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>_x000D_
<input type="radio" name="test" id="radio" /> <label for="radio">Radio</label>
_x000D_
_x000D_
_x000D_


Instead of getting the checked value you are setting it with:

var checked = $(this).attr('checked', true);

To properly get it:

var checked = $(this).attr('checked');

A working solution (with multiple radio buttons having different values):

// select radio buttons group (same name)
var radioButtons = $("input[type='radio'][name='rr']");
// save initial ckecked states
var radioStates = {};
$.each(radioButtons, function(index, rd) {
    radioStates[rd.value] = $(rd).is(':checked');
});

// handle click event
radioButtons.click(function() {
    
    // check/unchek radio button
    var val = $(this).val();  
    $(this).prop('checked', (radioStates[val] = !radioStates[val]));    
    
    // update other buttons checked state
    $.each(radioButtons, function(index, rd) {
        if(rd.value !== val) {
            radioStates[rd.value] = false; 
        }
    });
});

P.S.: $().attr should be used instead of $().prop for jquery < 1.6

Demo: jsFiddle


If you're still up for more answers i have found that this works with all radio buttons:

<script type="text/javascript">
        jQuery(document).ready(function ($){
                    var allRadios = $('input[type=radio]')
                    var radioChecked;

                    var setCurrent = 
                                    function(e) {
                                        var obj = e.target;

                                        radioChecked = $(obj).attr('checked');
                                 }

                    var setCheck = 
                                function(e) {

                                    if (e.type == 'keypress' && e.charCode != 32) {
                                        return false;
                                    }

                                    var obj = e.target;

                         if (radioChecked) {
                         $(obj).attr('checked', false);
                         } else {
                         $(obj).attr('checked', true);
                         }
                             }    

                    $.each(allRadios, function(i, val){        
                         var label = $('label[for=' + $(this).attr("id") + ']');

                     $(this).bind('mousedown keydown', function(e){
                            setCurrent(e);
                        });

                        label.bind('mousedown keydown', function(e){
                            e.target = $('#' + $(this).attr("for"));
                            setCurrent(e);
                        });

                     $(this).bind('click', function(e){
                            setCheck(e);    
                        });

                    });
        });
</script>

I believe this is the problem: If you have more than one radio button, and one of them is clicked, there is no way to deselect all of them. What is needed is a "none or only one" selector, so checkboxes would not be appropriate. You could have a "clear" button or something like that to deselect all, but it would be nice to just click the selected radio button to deselect it and go back to the "none" state, so you don't clutter your UI with an extra control.

The problem with using a click handler is that by the time it is called, the radio button is already checked. You don't know if this is the initial click or a second click on an already checked radio button. So I'm using two event handlers, mousedown to set the previous state, then the click handler as used above:

$("input[name=myRadioGroup]").mousedown(function () 
{
    $(this).attr('previous-value', $(this).prop('checked'));
});

$("input[name=myRadioGroup]").click(function () 
{
    var previousValue = $(this).attr('previous-value');

    if (previousValue == 'true')
        $(this).prop('checked', false);
});

-- EDIT --

It sure looks like your code is forcing a radio input to behave like a checkbox input. You might think about just using a checkbox input without the need for jQuery. However, if you want to force, like @manji said, you need to store the value outside the click handler and then set it on each click to the opposite of what it is at that time. @manji's answer is correct, I would just add that you should cache jQuery objects instead of re-querying the DOM:

var $radio = $("#radioinstant"),
    isChecked = $radio.attr("checked");

$radio.click(function() {

    isChecked = !isChecked;
    $(this).attr("checked", isChecked);

});

here is simple solution i hope it will help you. here's a simple example to improve answer.

$('[type="radio"]').click(function () {

            if ($(this).attr('checked')) {

                $(this).removeAttr('checked');
                $(this).prop('checked',false);

            } else {

                $(this).attr('checked', 'checked');

            }
        });

Demo sorry for too late.. :)


Best and shortest solution. It will work for any group of radios (with the same name).

$(document).ready(function(){
    $("input:radio:checked").data("chk",true);
    $("input:radio").click(function(){
        $("input[name='"+$(this).attr("name")+"']:radio").not(this).removeData("chk");
        $(this).data("chk",!$(this).data("chk"));
        $(this).prop("checked",$(this).data("chk"));
        $(this).button('refresh'); // in case you change the radio elements dynamically
    });
});

More information, here.

Enjoy.


I was having a related problem - I had to open a dialog box from dropdown based on selection from dropdown I will showing one or two radio button. Only one radio button can be activated at a time.

  • Option 1 will show two radio button with 1st radio selected
  • Option 2 will show second radio button and selected.

The script works some time some time it injects the checked but checkbox still unchecked

I went to jQuery .prop(), seems like jquery .prop() .attr() has some complication with radio buttons while using attr or prop. So What I did instead is trigger the click on the radio button based on Select value.

That resolve the need of using attr or prop or using on off lengthy code.

myForm = $("#myForm");

if (argument === 'multiple') {
            myForm.find('#radio1').parent('li').hide();
            myForm.find('#radio2').trigger('click');
    }
    else{
        myForm.find('#radio1').trigger('click');
         myForm.find('#radio1').parent('li').show();
    }

Not sure if this is best practice but it - Works like charm


I have a related but different scenario. Following is what I am doing:

Note: Code to select/unselect all radio buttons of class 'containerRadio' when the main radio button is selected.

CODE

        $('#selectAllWorkLot').click (function ()
        {

              var previousValue = $(this).attr('previousValue');

              if (previousValue == 'checked')
              {
                resetRadioButtonForSelectAll();

                //Unselect All
                unSelectAllContainerRadioButtons();
              }
              else
              {
                $(this).attr('previousValue', 'checked');

                //Select All
                selectAllContainerRadioButtons();
              }
        });


        function resetRadioButtonForSelectAll()
        {
            $('#selectAllWorkLot').removeAttr('checked');
            $('#selectAllWorkLot').attr('previousValue', false);
            //$('#selectAllWorkLot').prop('checked', false);
        }


        function selectAllContainerRadioButtons()
        {
            $('.containerRadio').prop('checked', true);
        }

        function unSelectAllContainerRadioButtons()
        {
            $('.containerRadio').prop('checked', false);
        }

Simplest solution. For both Radio and Checkboxes.

$('body').on('click', 'input[type="checkbox"]', function(){
    if ($(this).attr('checked')){
        $( this ).attr( 'checked', false);
    } else {
        $( this ).attr( 'checked', true);
    }
});
$('body').on('click', 'input[type="radio"]', function(){
    var name = $(this).attr('name');
    $("input[name="+name+"]:radio").attr('checked', false);
    $( this ).attr( 'checked', true);
});

If you use on click and only check if radio is checked and then deselect, you will never get the radio checked. So maybe easiest is to use classnames like this:

if($(this).hasClass('alreadyChecked')) {//it is already checked
        $('.myRadios').removeClass('alreadyChecked');//remove from all radios
        $(this).prop('checked', false);//deselect this
    }
    else {
        $('.myRadios').removeClass('alreadyChecked');//remove from all
        $(this).addClass('alreadyChecked');//add to only this
    }

This last solution is the one that worked for me. I had problem with Undefined and object object or always returning false then always returning true but this solution that works when checking and un-checking.

This code shows fields when clicked and hides fields when un-checked :

$("#new_blah").click(function(){
   if ($(this).attr('checked')) {

            $(this).removeAttr('checked');
    var radioValue = $(this).prop('checked',false);
    // alert("Your are a rb inside 1- " + radioValue);
    // hide the fields is the  radio button is no     
    $("#new_blah1").closest("tr").hide();
    $("#new_blah2").closest("tr").hide();

    } 
    else {

    var radioValue =  $(this).attr('checked', 'checked');
    // alert("Your are a rb inside 2 - " + radioValue);
    // show the fields   when radio button is set to  yes
    $("#new_blah1").closest("tr").show();
    $("#new_blah2").closest("tr").show();

}

DiegoP,

I was having the same trouble, until I realized that the check on the box doesnt go off until the attribute is removed. That means even if checked value is made false, it will remain there.

Hence use the removeAttr() function and remove the checked attrib and it WILL DEFINITELY WORK.


toggleAttr() is provided by this very nice and tiny plugin.

Sample code

$('#my_radio').click(function() {
    $(this).toggleAttr('checked');
});

/**
 * toggleAttr Plugin
 */
jQuery.fn.toggleAttr = function(attr) {
    return this.each(function() {
        var $this = $(this);
        $this.attr(attr) ? $this.removeAttr(attr) : $this.attr(attr, attr);
    });
};

Even more fun, demo

You can use place your radio button inside label or button tags and do some nice things.


$(document).ready(function(){ $("input:radio:checked").data("chk",true);

$("input:radio").click(function(){
    $("input[name='"+$(this).attr("name")+"']:radio").not(this).removeData("chk");

    $(this).data("chk",!$(this).data("chk"));

    $(this).prop("checked",$(this).data("chk"));
});

});


I think this is the shortest way. I tested it on Chrome and MS Edge.

$(document).on('click', 'input:radio', function () {
    var check = $(this).attr('checked')
    if (check) $(this).removeAttr('checked').prop('checked',false)
    else $(this).attr('checked', true).prop('checked',true)
})

This piece of code also works on AJAX loaded contents.

Alternatively, You can also use

$(document).on('click mousedown', 'input:radio', function (e) {
    e.preventDefault()
    if ($(this).prop('checked')) $(this).prop('checked', false)
    else $(this).prop('checked', true)
})

This would work better without any exceptions.


I would suggest this:

$('input[type="radio"].toggle').click(function () {
    var $rb = $(this);

    if ($rb.val() === 'on') {
        $rb.val('off');
        this.checked = false;
    }
    else {
        $rb.val('on');
        this.checked = true;
    }
});

Your HTML would look like this:

<input type="radio" class="toggle" value="off" />

This function will add a check/unchecked to all radiobuttons

jQuery(document).ready(function(){
jQuery(':radio').click(function()
{
if ((jQuery(this).attr('checked') == 'checked') && (jQuery(this).attr('class') == 'checked'))
{   
    jQuery(this).attr('class','unchecked');
    jQuery(this).removeAttr('checked');
} else {
jQuery(this).attr('class','checked');
}//or any element you want

});
});

Having tested some of the above solutions which did not work for me 100%, I decided to create my own. It creates new click listeners after a radio button is clicked:

/**
 * Radio select toggler
 * enables radio buttons to be toggled when clicked
 * Created by Michal on 09/05/2016.
 */

var radios = $('input[type=radio]');

/**
 * Adds click listeners to all checkboxes to unselect checkbox if it was checked already
 */
function updateCheckboxes() {
    radios.unbind('click');
    radios.filter(':checked').click(function () {
        $(this).prop('checked', false);
    });
    radios.click(function () {
        updateCheckboxes();
    });
}

updateCheckboxes();

Improved version of answer from Jurrie

$('#myRadio').off('click').on('click', function() {
  if ($(this).data('checked')) {
    $(this).removeAttr('checked');
    $(this).data('checked', false);
  } else {
    $(this).data('checked', true);
  }
});

Live Demo