How can I toggle radiobutton
Asked Answered
C

9

18

Say this is my HTML:

<input type="radio" name="rad" id="Radio0" checked="checked" />
<input type="radio" name="rad" id="Radio1" />
<input type="radio" name="rad" id="Radio2" />
<input type="radio" name="rad" id="Radio4" />
<input type="radio" name="rad" id="Radio3" />

As you can see the 1st radio button is checked. I need the radio button to function like toggle. For eg. If I again click on radio0, all radio buttons should be unchecked.

How can I achieve that?

Update: I don't want any extra buttons. For eg. I could add a button and set the checked property for all radio buttons to be false. However, I don't want that. I only want my form to consist of these 4 radio buttons.

Update: Since most of the people don't understand what I want, let me try to rephrase- I want the radio button to function in toggle mode. I've given the same name to all radio buttons hence it's a group. Now I want the radiobuttons to toggle itself. Eg. if I click on radio0, it should get unchecked if it's checked and checked if it's unchecked.

Couplet answered 27/2, 2013 at 6:18 Comment(5)
i think it is "all radio buttons should be checked"Dwain
@Toms: What do you mean?Couplet
You can not select multiple radio buttons belonging to same gruop(with same "name" value).. Please think of checkboxes.Individual
Radio buttons that share the same name attribute automatically act as a group so that only one can be checked at a time. The question does not specify how this should be changed (still less why), so it’s like saying you want 2 + 2 to be 4.Loo
I wouldn't suggest doing this, it may confuse your users. It's more common practice to have an extra "no selection" radio button or provide a <select> block with a "no selection" <option> if you want to be more concise. The point of radio buttons is to make your user chose exactly one option, they should never need to unselect all radio buttons.Toponymy
P
34

The problem you'll find is that as soon a radio button is clicked its state is changed before you can check it. What I suggest is to add a custom attribute to keep track of each radio's previous state like so:

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

        // if this was previously checked
        if ($radio.data('waschecked') == true)
        {
            $radio.prop('checked', false);
            $radio.data('waschecked', false);
        }
        else
            $radio.data('waschecked', true);

        // remove was checked from other radios
        $radio.siblings('input[name="rad"]').data('waschecked', false);
    });
});

You will also need to add this attribute to the initially checked radio markup

<input type="radio" name="rad" id="Radio0" checked="checked" data-waschecked="true" />

See demo here : http://jsfiddle.net/GoranMottram/VGPhD/2/

Prajna answered 27/2, 2013 at 6:39 Comment(4)
Excellennt!! Exactly the behavior that I needed.Couplet
There is a small issue. When I click the 1st radio the 1st time. It still remains checked. Can you reproduce it?Couplet
Ah yes, I've updated the answer with the fix. Sorry about that.Prajna
Ridiculous that the question was ever closed. Perfectly reasonable question, with a perfectly reasonable answer.Jacinda
B
11

Once you give the name of 2 or more radio buttons as the same, they automatically become a group. In that group only one radio button can be checked. You have already achieved this.

Basque answered 27/2, 2013 at 6:22 Comment(1)
name groups the radio buttons, ids allows to know which one is checked, and tell the others they are not, and value let's you know what every radio button is or means. See: w3schools.com/tags/att_input_type_radio.aspBloomfield
R
4

This code solved my issue

$("[type='radio']").on('click', function (e) {
    var previousValue = $(this).attr('previousValue');
    if (previousValue == 'true') {
        this.checked = false;
        $(this).attr('previousValue', this.checked);
    }
    else {
        this.checked = true;
        $(this).attr('previousValue', this.checked);
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<label >Toogle radio button example</label>
<br />
<input type="radio" name="toogle_me" value="mango"> Blue </input>
<input type="radio" name="toogle_me" value="kiwi"> Green </input>
<input type="radio" name="toogle_me" value="banana"> Yellow </input>
<input type="radio" name="toogle_me" value="orange"> Orange </input>
Rabblerousing answered 16/8, 2018 at 13:34 Comment(0)
G
0

I use an onClick() like the following for my custom radios:

$(function(){
  // if selected already, deselect
  if ($(this).hasClass('selected') {
    $(this).prop('checked', false);
    $(this).removeClass('selected');
  }
  // else select
  else {
    $(this).prop('checked', true);
    $(this).addClass('selected');
  }
  // deselect sibling inputs
  $(this).siblings('input').prop('checked', false);
  $(this).siblings('input').removeClass('selected');
}
Grayce answered 22/8, 2017 at 14:54 Comment(0)
L
0

Using @Goran Mottram answer just tweaking it a bit to suit the case where radio buttons are not siblings.

$(".accordian-radio-button").click(function(){
    var wasChecked = true;
    if($(this).data('waschecked') == true){
        $(this).prop('checked', false);
        wasChecked = false;
    }
    $('input[name="ac"]').data('waschecked', false);
    $(this).data('waschecked', wasChecked);
})

<input class="accordian-radio-button" data-waschecked="false" type="radio" name="ac" id="a1" />
Luhe answered 28/3, 2018 at 23:25 Comment(0)
P
0

I ran into this as well, after thinking about it and playing around with the various fiddles offered, I had a few dissatisfactions with the offered solutions.

My main problem was the last line of the accepted answer, requiring a reset:

// remove was checked from other radios
    $radio.siblings('input[name="rad"]').data('waschecked', false);

And since I'm not using jQuery, I'd have to loop over and evaluate the siblings myself, which isn't a huge deal, but seemed inelegant to me. But, there's no way around it with that method, because you're using the dataset as a storage of information.

After playing around, I realized is that the problem is that when a radio is clicked, it triggers the clicked event, and whatever function is attached to that click event completes itself before the function for the "onchange" event is ever evaluated, let alone called. So, if the click event "unchecks" the toggle, then no change event is ever fired.

I've left my failed attempt here: https://codepen.io/RiverRockMedical/pen/daMGVJ

But, if you could answer the question "will a change event happen after this click event?" then you could get a toggle working.

The solution I came up with can be seen at this pen: https://codepen.io/RiverRockMedical/pen/VgvdrY

But basically is as follows:

function onClick(e) {
  e.dataset.toDo = 'uncheck';
  setTimeout(uncheck, 1, {
    event:'click',
    id:e.id,
    dataset:e.dataset
  });
}

So, on the click event, set a marker that the click has happened, and the use setTimeout() to create a pause that allows the onchange event to be evaluated and fire.

function onChange(e) {
  e.dataset.toDo = 'leave';
}

If the onchange event fires, it undoes what was done by the onclick event.

function uncheck(radio) {
  log('|');
  if (radio.event !== 'click') return;
  log('uncheck');
  if (radio.dataset.toDo === 'uncheck') {
    document.getElementById(radio.id).checked = false;
    radio.checked = false;
  } 
}

Then, when the uncheck function starts, it has the information of whether a change event followed the click event or not. If not, then the radio is unchecked, and functions as a toggle.

And, it's basically self-resetting, so I don't have to loop over all the radios and reset their datasets to the initial values at the end of the function.

Now, I'm sure there's a cooler async/await way to do this that doesn't use setTimeout and would be even more elegant, but I'm still learning and I couldn't come up with it. Anyone else?

Pocketful answered 26/1, 2019 at 21:9 Comment(0)
S
0
<input type="radio" name="gender" id="male"onclick="getChecked(1)"><label for="male">Male</label>
<input type="radio" name="gender" id="female"onclick="getChecked(2)"><label for="female">female</label>
<script>
  var btnChecked = "";
  function getChecked(i) {
    if(btnChecked == i) {
      btnChecked = "";
      document.getElementsByTagName("input")[i-1].checked = false;
    }
    else btnChecked = i;
  }
</script>    
Slap answered 30/4, 2020 at 11:58 Comment(0)
G
0

A simple approach in jQuery (even though I don't use jQuery nowdays):

function makeRadioInputsToggleable(radioInputs){
  let radioGroup = {
    lastValue: radioInputs.filter(':checked').prop('value'),
    get value(){
      return this.lastValue;
    },
    set value(v){
      let inputToCheck = radioInputs.filter((i, el) => el.value === v);
      radioInputs.filter(':checked').prop('checked', false);
      if(inputToCheck.length > 0){
        inputToCheck.prop('checked', true);
        this.lastValue = v;
      }else{
        this.lastValue = undefined;
      }
    },
  };
  radioInputs.on('click', (e) => {
    let input = e.target;
    if(input.value === radioGroup.lastValue){
      input.checked = false;
      radioGroup.lastValue = undefined;
    }else{
      radioGroup.lastValue = input.value;
    }
  }).on('keydown', (e) => {
    if(e.code === 'Space'){
      let input = e.target;
      if(input.checked){
        input.checked = false;
        input.blur();
        radioGroup.lastValue = undefined;
      }
    }
  });
  return radioGroup;
}

let radioInputs = $('input[type="radio"][name="rad"]');
let radioGroup = makeRadioInputsToggleable(radioInputs);

$('.check-radio').on('click', (e)=>{
  let value = e.target.value;
  radioGroup.value = value;
});

// Note:
// 1. pass a single group of radio inputs to `makeRadioInputsToggleable`
// 2. set distinct values for each radio input in a group.
// 3. to change checked radio programmatically, use `radioGroup.value = 'XXX'` rather than radioInputs.prop('checked', false).filter('[value="XXX"]').prop('checked', true);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<h3>makeRadioInputsToggleable</h3>
<label><input type="radio" name="rad" value="1" id="Radio0" checked="checked" />1</label>
<label><input type="radio" name="rad" value="2" id="Radio1" />2</label>
<label><input type="radio" name="rad" value="3" id="Radio2" />3</label>
<label><input type="radio" name="rad" value="4" id="Radio4" />4</label>
<label><input type="radio" name="rad" value="5" id="Radio3" />5</label>
<p>1. click on an already-checked radio button, the radio will be toggled to unchecked.</p>
<p>2. focus on an already-checked radio button and press 'Space', the radio will be toggled to unchecked. <i>(This may not work in Code Snippet result area)</i></p>
<p>
  3. programmatically
  <button class="check-radio" value="2">check radio with value 2</button>
  <button class="check-radio" value="10">check radio with value 10</button>
</p>
Grasp answered 2/4, 2022 at 4:11 Comment(0)
F
0

Dont need js fot that, just html and, optionally, a bit of css:

input[data-none] { 
  display: none; 
}
input[data-none] + ul li { 
  position: relative;  
  display: flex;
  list-style: none;
  padding: 1em;
  margin: 0;
}   
input[data-none] + ul li input { 
  display: block;
  width: 32px;
  height: 32px;
  padding: 0;
  margin: 0;
  cursor: pointer;
}
input[data-none] + ul li label { 
  display: none;
  width: 32px;
  height: 32px;
  margin-left: -32px;
  cursor: pointer;
}           
input[data-none] + ul li input:checked + label { 
  display: block; 
}           
<input type="radio" name="rad" id="radionone" value="" data-none>
<ul>
  <li><input type="radio" name="rad" id="radio0" checked="checked"><label for="radionone"></label></li>
  <li><input type="radio" name="rad" id="radio1"><label for="radionone"></label></li>
  <li><input type="radio" name="rad" id="radio2"><label for="radionone"></label></li>
  <li><input type="radio" name="rad" id="radio4"><label for="radionone"></label></li>
  <li><input type="radio" name="rad" id="radio3"><label for="radionone"></label></li>
</ul>
Firstly answered 30/7 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.