web-dev-qa-db-fra.com

jQuery cocher/décocher la case d'option onclick

J'ai ce code pour cocher/décocher un bouton radio onclick.

Je sais que ce n'est pas bon pour l'interface utilisateur, mais j'ai besoin de ça.

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

La fonction ci-dessus ne fonctionne pas.

Si je clique sur le bouton, rien ne change. Il reste coché. Pourquoi? Où est l'erreur? Je ne suis pas un expert jQuery. Je suis sur jQuery 1.3.2

Pour être clair, #radioinstant est l'ID du bouton radio.

39
DiegoP.

Si tout ce que vous voulez, c’est une case à cocher qui coche, ne vous inquiétez pas de le faire avec JQuery. C'est la fonctionnalité par défaut d'une case à cocher au clic. Cependant, si vous voulez faire des choses supplémentaires, vous pouvez les ajouter avec JQuery. Avant jQuery 1.9, vous pouvez utiliser $(this).attr('checked'); pour obtenir la valeur au lieu de $(this).attr('checked', true);, car le second définira la valeur. 

Ici est une démonstration de violon qui montre la fonctionnalité de case à cocher par défaut par rapport à ce que vous faites avec JQuery. 

Remarque: Après JQuery 1.6, vous devez utiliser $(this).prop; au lieu de $(this).attr aux trois endroits (merci @Whatevo de l'avoir signalé et voir ici pour plus de détails ). 

METTRE À JOUR:

Désolé, j'ai manqué l'exigence voulant qu'il s'agisse d'un bouton radio. Vous voudrez peut-être quand même considérer la case à cocher, mais ici est le code mis à jour pour la version d'entrée radio. Cela fonctionne en définissant la previousValue comme attribut sur la case à cocher, car je ne pense pas que prop soit supporté dans la version 1.3.2. Vous pouvez également le faire dans une variable étendue, car certaines personnes n'aiment pas définir des attributs aléatoires sur les champs. Ici est le nouvel exemple.

UPDATE 2:

Comme Josh l'a souligné, la solution précédente ne fonctionnait qu'avec un seul bouton radio. Voici une fonction qui permet de désélectionner un groupe de radios par leur nom et un violon :

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

J'ai développé les suggestions précédentes… .. Cela fonctionne pour moi, avec plusieurs radios couplées du même nom.

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

Au lieu d'obtenir la valeur cochée, vous la définissez avec:

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

Pour bien l'obtenir:

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

Une solution de travail (avec plusieurs boutons radio ayant des valeurs différentes):

// 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 doit être utilisé à la place de $().prop pour jquery <1.6

Démo: jsFiddle

13
manji

La solution la meilleure et la plus courte. Cela fonctionnera pour n'importe quel groupe de radios (avec le même nom).

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

Plus d'informations, ici .

Prendre plaisir.

12
Slavik Meltser

Je crois que c’est le problème: si vous avez plus d’un bouton radio et que l’on clique sur l’un d’eux, il n’ya aucun moyen de les désélectionner tous. Ce qu'il faut, c'est un sélecteur "aucun ou un seul". Les cases à cocher ne seraient donc pas appropriées. Vous pouvez avoir un bouton "effacer" ou quelque chose comme ça pour tout désélectionner, mais il serait agréable de simplement cliquer sur le bouton radio sélectionné pour le désélectionner et revenir à l'état "aucun", afin de ne pas encombrer votre interface utilisateur un contrôle supplémentaire.

Le problème avec l'utilisation d'un gestionnaire de clic est qu'au moment où il est appelé, le bouton radio est déjà coché. Vous ne savez pas s’il s’agit du premier clic ou d’un deuxième clic sur un bouton radio déjà coché. J'utilise donc deux gestionnaires d'événements, mousedown pour définir l'état précédent, puis le gestionnaire de clic utilisé précédemment:

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

toggleAttr() est fourni par ce très joli et minuscule plugin .

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

Encore plus amusant, démo

Vous pouvez utiliser le bouton radio placé à l’intérieur de l’étiquette ou le bouton et faire des choses agréables.

2
Nabil Kadimi

Après avoir testé certaines des solutions ci-dessus qui ne fonctionnaient pas à 100% pour moi, j'ai décidé de créer la mienne. Il crée de nouveaux écouteurs après avoir cliqué sur un bouton radio:

/**
 * 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();
1
mick88

Version améliorée de la réponse de Jurrie

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

Démo en direct

1

$ (document) .ready (fonction () { $ ("entrée: radio: vérifié"). 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"));
});

});

1
Aarti Goyal

J'ai un scénario lié mais différent. Voici ce que je fais:

Remarque: Code permettant de sélectionner/désélectionner tous les boutons radio de la classe 'containerRadio' lorsque le bouton radio principal est sélectionné.

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

DiegoP,

J'avais le même problème, jusqu'à ce que je réalise que la case à cocher de la case ne disparaît que lorsque l'attribut est supprimé. Cela signifie que même si la valeur cochée est fausse, elle y restera.

Par conséquent, utilisez la fonction removeAttr () et supprimez l'attribut coché et il FONCTIONNERA ENFIN.

0
iamkhush

-- MODIFIER --

Il semble bien que votre code force une entrée radio à se comporter comme une entrée à case à cocher. Vous pourriez penser à utiliser simplement une entrée de case à cocher sans avoir besoin de jQuery. Cependant, si vous voulez forcer, comme @manji l'a dit, vous devez stocker la valeur en dehors du gestionnaire de clics, puis la définir à chaque clic à l'opposé de ce qu'elle est à ce moment-là. La réponse de @ manji est correcte, je voudrais simplement ajouter que vous devez mettre en cache les objets jQuery au lieu de réinterroger le DOM:

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

$radio.click(function() {

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

});
0
Code Maverick

voici une solution simple, j'espère que cela vous aidera. voici un exemple simple pour améliorer la réponse.

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

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

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

            } else {

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

            }
        });

Démo Désolé pour trop tard .. :)

0
sajid

Les solutions que j'ai essayées à partir de cette question ne fonctionnaient pas pour moi. Parmi les réponses qui ont fonctionné partiellement, j'ai quand même constaté que je devais cliquer deux fois sur le bouton radio précédemment décoché pour le vérifier à nouveau. J'utilise actuellement jQuery 3+.

Après avoir essayé de faire en sorte que cela fonctionne à l'aide d'attributs de données ou d'autres attributs, j'ai finalement compris la solution en utilisant plutôt une classe.

Pour votre entrée radio vérifiée, donnez-lui la classe checked par exemple:

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

Voici le 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');
    }
});
0
kjdion84

J'ai pris https://stackoverflow.com/a/13575528/80353 et je l'ai adapté comme ceci

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

    });
0
Kim Stacks

Cette fonction ajoutera un contrôle/décoché à tous les boutons radio.

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

});
});
0
Remco

Cette dernière solution est celle qui a fonctionné pour moi. J'ai eu un problème avec Undefined et objet object ou toujours en retournant false puis toujours en retournant true, mais cette solution fonctionne lors de la vérification et la désélection.

Ce code affiche les champs lorsque vous cliquez dessus et masque ceux-ci lorsqu'ils sont décochés:

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

}
0
user7957126

Je suggérerais ceci:

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

Votre code HTML ressemblerait à ceci:

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

J'avais un problème connexe - je devais ouvrir une boîte de dialogue à partir d'une liste déroulante en fonction d'une sélection dans une liste déroulante. Un bouton radio apparaît. Un seul bouton radio peut être activé à la fois.

  • L'option 1 affichera deux boutons radio avec la 1ère radio sélectionnée
  • L'option 2 affichera le deuxième bouton radio et sélectionné.

Le script fonctionne un certain temps, il injecte la case cochée mais la case toujours cochée

Je suis allé à jQuery .prop() , semble que jquery .prop() .attr() a quelques complications avec les boutons radio tout en utilisant attr ou prop. Donc, ce que j’ai fait à la place, c’est de déclencher le clic sur le bouton radio en fonction de Sélectionner une valeur.

Cela résout le besoin d'utiliser attr ou prop ou d'utiliser un code trop long.

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

Pas sûr que ce soit la meilleure pratique mais ça fonctionne comme un charme

0
Shraftali

Si vous souhaitez toujours plus de réponses, j'ai constaté que cela fonctionne avec tous les boutons radio:

<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>
0
Nicole

Si vous utilisez au clic et vérifiez seulement si la radio est cochée puis désélectionnée, la radio ne sera jamais cochée. Alors peut-être que le plus simple est d'utiliser des noms de classe comme ceci:

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
    }
0