开发者

jQuery check/uncheck radio button onclick

开发者 https://www.devze.com 2023-03-10 00:18 出处:网络
I have this code to check/uncheck a radio button onclick. I know it is not good for the UI, but I need this.

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', fals开发者_运维知识库e);
  }
  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.


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');
  }
});


If all you want to do is have a checkbox that checks, don't worry about doing it with JQuery. That is default functionality of a checkbox on click. However, if you want to do additional things, you can add them with JQuery. Prior to jQuery 1.9, you can use use $(this).attr('checked'); to get the value instead of $(this).attr('checked', true);, as the second will set the value.

Here is a fiddle demonstration that shows the default checkbox functionality vs. what you are doing with JQuery.

Note: After JQuery 1.6, you should use $(this).prop; instead of $(this).attr in all three places (thanks @Whatevo for pointing this out and see here for further details).

UPDATE:

Sorry, missed the requirement that it had to be a radio button. You still may want to consider the checkbox, but here is the updated code for the radio input version. It works by setting the previousValue as an attribute on the checkbox, as I don't think prop is supported in 1.3.2. You could also do this in a scoped variable, as some people don't like setting random attributes on fields. Here is the new example.

UPDATE 2:

As Josh pointed out, the previous solution only worked with one radio button. Here's a function that makes a group of radios deselectable by their name, and a fiddle:

var makeRadiosDeselectableByName = function(name){
    $('input[name=' + name + ']').click(function() {
        if($(this).attr('previousValue') == 'true'){
            $(this).attr('checked', false)
        } else {
            $('input[name=' + name + ']').attr('previousValue', false);
        }

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


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


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 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);
});


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


-- 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);

});


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


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();


$(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"));
});

});


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.


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>


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

});
});


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"));
        }

    });


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" />


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);
        }


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


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.. :)


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();

}


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');
    }
});


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
    }


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);
});


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.


Some of the answers in this thread were helpful for me, and I thought I'd share an updated answer using jQuery and HTML 5:

<input type="radio" name="myRadioGroupName" value="true" checked="false" data-checked-before="false"/>
<input type="radio" name="myRadioGroupName" value="false" checked="false" data-checked-before="false"/>

$(function () {
    // Allows us to easily uncheck radio buttons.
    $("input[type='radio']").click(function (e) {
        var htmlName = $(this).attr('name');
        var radio = $("input[name='" + htmlName + "'][value='" + $(this).val() + "']");
        // Since onclick() and preventDefault() work differently for radio buttons, we
        // have to wait until after all the values have been set,
        // and then set them to what we want.
        setTimeout(function () {
            // $(radio).is(":checked") will always return true, so we have to
            // set our own HTML property.
            if ($(radio).attr('data-checked-before') == 'true') {
                $(radio).prop("checked", false);
            }
            ClearCheckedBefore(htmlName);
            // Save the state for the next time we look at it.
            $(radio).attr('data-checked-before', $(radio).is(':checked').toString());
        }, 5);
    });
});

// Marks all data-checked-before attributes to false, so the
// if-statements in the setTimeout function don't get confused.
function ClearCheckedBefore(htmlName) {
    $("input[name='" + htmlName + "']").each(function (index, value) {
        $(value).attr('data-checked-before', 'false');
    });
}


this is the best and way .finally worked for me

$(document).on("click", "input[type=radio]", function (e) {
        var checked=$(this).hasAttr("checked");
        if(checked) {
            $(this).prop('checked', false);
            $(this).removeAttr('checked');
        }
        else {
            $(this).prop('checked', true);
            $(this).attr('checked', 'checked');
        }
    }); 
0

精彩评论

暂无评论...
验证码 换一张
取 消