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.
<try this:
$('input[type=radio]').click(function(){
if (this.previous) {
this.checked = false;
}
this.previous = this.checked;
});
Here's a super lightweight script you can add to a page through the console window that allows you to deselect a radio button by holding down Ctrl while clicking it with the mouse.
document.addEventListener('click', function(e){
if (e.ctrlKey == true &&
e.target.tagName == 'INPUT' &&
e.target.type == "radio" &&
e.target.checked == true) {
e.target.checked = false;
}
});
Since it doesn't rely on jQuery, you can easily add it to any page to temporarily allow deselection.
For slightly more info, you can read an article I just wrote on How To Deselect A Radio Button.
As HexInteractive mentioned, radio button is handled outside the normal event chain. So, following example judges the button state by class name, not by property.
var $self;
$('input[type=radio]').on('click', function() {
$self = $(this);
if ( $self.hasClass('is-checked') ) {
$self.prop('checked', false).removeClass('is-checked');
} else {
$self.addClass('is-checked');
}
});
It is better UX to have a default-selected "Select none" explicit option, and not let the user uncheck any radio button.
(List item 9 in this nngroup (neilsen) article:
http://www.nngroup.com/articles/checkboxes-vs-radio-buttons/
I must be missing it but after all these years AFAIK none of the solutions above seem to work or maybe I'm just dumb.
There is absolutely no reason to use a radio button unless there is more than one radio button in the same group. If it's a lone radio button then just use a checkbox. The reason to use a radio button is for selecting one of mutually exclusive options. That means any solution which only looks at individual buttons will fail since clicking a one button will effect the state of the other buttons
In other words since we're using radioboxes the solution needs to work for
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>
Here's one that looks at all the buttons.
This seems to work
document.querySelectorAll(
'input[type=radio][name=foo]').forEach((elem) => {
elem.addEventListener('click', allowUncheck);
// only needed if elem can be pre-checked
elem.previous = elem.checked;
});
function allowUncheck(e) {
if (this.previous) {
this.checked = false;
}
// need to update previous on all elements of this group
// (either that or store the id of the checked element)
document.querySelectorAll(
`input[type=radio][name=${this.name}]`).forEach((elem) => {
elem.previous = elem.checked;
});
}
body { font-size: xx-large; }
label, input {
/* added because a second click to unselect radio often
appears as a double click to select text */
-webkit-user-select: none;
user-select: none;
}
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>
note if elem.previous
worries you you could use elem.dataset.previous
Another solution would be to store which button is checked
function makeRadioboxGroupUnCheckable(groupSelector) {
let currentId;
document.querySelectorAll(groupSelector).forEach((elem) => {
elem.addEventListener('click', allowUncheck);
// only needed if can be pre-checked
if (elem.checked) {
currentId = elem.id;
}
});
function allowUncheck(e) {
if (this.id === currentId) {
this.checked = false;
currentId = undefined;
} else {
currentId = this.id;
}
}
}
makeRadioboxGroupUnCheckable('input[type=radio][name=foo]');
body { font-size: xx-large; }
label, input {
/* added because a second click to unselect radio often
appears as a double click to select text */
-webkit-user-select: none;
user-select: none;
}
<input type="radio" name="foo" id="foo1"><label for="foo1">foo1</label>
<input type="radio" name="foo" id="foo2"><label for="foo2">foo2</label>
<input type="radio" name="foo" id="foo3"><label for="foo3">foo3</label>
Based on answer by Stephen - this deals with multiple radio button groups and also you mostly don't need to double click radio buttons. It isn't perfect as if you switch between groups the check for id will necessitate an extra click but works ok.
$("input[type='radio']").on('click', function (e) {
if (this.previous && this.value == previousvalue && this.id == previousid) {
this.checked = false;
}
this.previous = this.checked;
previousvalue = this.value;
previousid = this.id;
});