I want to be able to uncheck a radio button by clicking on it.
So, if a radio button is unchecked, I want to check it, if it is checked, I want to uncheck it.
<This is not to replace a checkbox, it's to allow a radio group to go back to an unselected state. This was tricky because the radio selection doesn't act like a normal event.
The browser handles radio buttons outside the normal event chain. So, a click handler on a radiobutton with event.preventDefault() or event.stopPropagation() will NOT prevent the radiobutton from being checked. The .removeAttr('checked') must be done in a setTimeout to allow the event to finish, and the browser to check the radiobutton (again), and then the setTimeout will fire.
This also correctly handles the case where a user starts the mousedown but leaves the radiobutton before mouseup.
//$ = jQuery;
$(':radio').mousedown(function(e){
var $self = $(this);
if( $self.is(':checked') ){
var uncheck = function(){
setTimeout(function(){$self.removeAttr('checked');},0);
};
var unbind = function(){
$self.unbind('mouseup',up);
};
var up = function(){
uncheck();
unbind();
};
$self.bind('mouseup',up);
$self.one('mouseout', unbind);
}
});
I hope this helps
Using prop function with checked as key:
$("input:radio").prop("checked",false);
The accepted answer does not work on mobile devices. It relies on setTimeout and bindings that are related to mouse events that just don't fire on tablets/mobile devices.
My solution is to manually track the selected state using the "click" event handler and a custom class state.
No need to prevent default behaviors. Here is the code in Jquery:
$("input:radio").on("click",function (e) {
var inp=$(this); //cache the selector
if (inp.is(".theone")) { //see if it has the selected class
inp.prop("checked",false).removeClass("theone");
return;
}
$("input:radio[name='"+inp.prop("name")+"'].theone").removeClass("theone");
inp.addClass("theone");
});
http://jsfiddle.net/bhzako65/
This is the real solution ...
var check;
$('input[type="radio"]').hover(function() {
check = $(this).is(':checked');
});
$('input[type="radio"]').click(function() {
check = !check;
$(this).attr("checked", check);
});
Try it, it works for me!
Who those who are seeking for a pure JavaScript solution I modified the code from Jase in ATL's answer.
I wrote this code for proposal of use with a CSS styled 3 position switch which provides 4 state of toggling (On, Off, Neutral and Unactivated).
function toggle_radio(ev) {
var radio = ev.target;
var cut_pos = radio.className.indexOf(' switcher-active');
// the switch itself
if (cut_pos !== -1) { // if the button checked it is '.switcher-active'
radio.checked = false; // toggle its state
radio.className = radio.className.slice(0, cut_pos); // remove '.switcher-active'
return true; // work is done. Break the function
}
// the button was inactive before it was clicked. Then it should became '.switcher-active'
radio.className = radio.className + ' switcher-active';
// we need to remove '.switcher-active' if either the left or right radio button was clicked. This part is uggly but I don't bother, because I'm late for barber
var radios = document.getElementsByName(radio.name); // get all these radio siblings as a collection of elements
for (var i=0; i < radios.length; i++) { // iterate through the collection
if (radios[i].className.indexOf('switcher-radio-neutral') !== -1)
continue; // skip the '.switcher-neutral' radio input
radios[i].onclick = function(ev2) {
sib_radios = document.getElementsByName(ev2.target.name); // get a group of radio inputs linked by the name
// get the '.switcher-neutral'
for (var k=0, cut_pos = -1, sib; k < sib_radios.length; k++) {
sib = sib_radios[k];
cut_pos = sib.className.indexOf(' switcher-active');
if (cut_pos !== -1)
sib.className = sib.className.slice(0, cut_pos);
}
}
}
}
var switchers = document.getElementsByClassName('switcher-radio-neutral');
for (var i=0; i < switchers.length; i++) { // bind onclick handlers
switchers[i].onclick = toggle_radio;
}
.switcher {
position: relative;
display: inline-block;
margin: 1px 10px;
height: 20px;
width: 58px;
z-index: 1;
}
.switcher-off {
left: 1px;
width: 33%;
height: 100%;
}
.switcher-neutral {
left: 33%;
width: 33%;
height: 100%;
}
.switcher-on{
right: 1px;
width: 33%;
height: 100%;
}
.switcher-label {
position: absolute;
text-indent: -9999px;
z-index: 2;
}
.switcher input {
visibility: hidden;
position: absolute;
}
.switcher-slider {
height: 100%;
width: 100%;
border-radius: 10px;
box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1) inset, 0 0 4px rgba(0, 0, 0, 0.5) inset, 0 2px 2px 1px rgba(0, 0, 0, 0.3) inset;
transition: background-color 0.2s linear 0s;
}
.switcher-slider:after {
transition: left 0.2s linear 0s, right 0.2s linear 0s;
background: linear-gradient(#D0D0D0, #FDFDFD) repeat scroll 0 0 rgba(0, 0, 0, 0);
content: "";
position: absolute;
top: 1px;
border-radius: 50%;
height: calc(100% - 2px);
width: calc(100%/3 - 1px);
box-shadow: 0 0 1px 1px #f4f4f4 inset, 0 0 3px 1px rgba(0, 0, 0, 0.6);
left: 33%;
}
.switcher-radio-on:checked ~ .switcher-slider {
background-color: #81EA89;
}
.switcher-radio-neutral:checked ~ .switcher-slider {
background: #ffffd;
}
.switcher-radio-off:checked ~ .switcher-slider {
background-color: #ED8282;
}
.switcher-radio-on:checked ~ .switcher-slider:after {
left: calc(2*(100%/3));
}
.switcher-radio-neutral:checked ~ .switcher-slider:after {
left: calc(1px + 100%/3);
}
.switcher-radio-off:checked ~ .switcher-slider:after {
left: 1px;
}
<form action="">
<input type="radio" name="radio_input" value="1">
<input type="radio" name="radio_input" class="switcher-radio-neutral" value="2">
<input type="radio" name="radio_input" value="3">
</form>
<br><br>
<div class="switcher">
<label class='switcher-label switcher-off' for='off'>off</label>
<input id='off' class='switcher-radio-off' type='radio' name='value' value='off'>
<label class='switcher-label switcher-neutral' for='neutral'>neutral</label>
<input id='neutral' class='switcher-radio-neutral' type='radio' name='value' value='neutral' data-neutral="">
<label class='switcher-label switcher-on' for='on'>on</label>
<input id='on' class='switcher-radio-on' type='radio' name='value' value='on'>
<div class='switcher-slider'></div>
</div>
Yes you can also do this on click checked, again click uncheck. Here is the logic of this:
$('input[name=check1]').prop('checked',!$('input[name=check1]').prop('checked'));