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