How to make a radio button unchecked by clicking it?
Asked Answered
C

31

104

Unlike check boxes, it is impossible for the user to deselect radio buttons once they are clicked. Is there any way so that they can be toggled programmatically using Javascript? This would be preferably without using jQuery.

Childbearing answered 4/6, 2012 at 6:5 Comment(1)
In chrome console, you can select that radio's html tag and in console use $0.checked=falseEducational
K
102

You can set HTML object's property checked to false like this:

document.getElementById('desiredInput').checked = false;

Examples

Plain JavaScript:

var radios = document.getElementsByTagName('input');
for(i=0; i<radios.length; i++ ) {
    radios[i].onclick = function(e) {
        if(e.ctrlKey || e.metaKey) {
            this.checked = false;
        }
    }
}
<input type="radio" name="test" value="1" />
<input type="radio" name="test" value="2" checked="checked" />
<input type="radio" name="test" value="3" />
jQuery:

$('input').click(function(e){
    if (e.ctrlKey || e.metaKey) {
        $(this).prop('checked', false);
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="radio" name="test" value="1" />
<input type="radio" name="test" value="2" checked="checked" />
<input type="radio" name="test" value="3" />

Hold down Ctrl ( on mac) key to uncheck.

Krona answered 4/6, 2012 at 6:13 Comment(7)
This is looking to be like what I need, but is there any way to do it without having to press Ctrl? Thanks!Childbearing
@JohnSawatzky sure, just remove the check if(e.ctrlKey) {...Krona
@Krona there is no way to make it checkTran
@pinkpanther, Absolutely not. I think this is the utter difficulty about this problem. Remove the if ctrlKey, and... well, you can uncheck it... but you can never check a radio because the [click] event-target's checked property will always show as checked.Erleena
Is there a way to say if a particular radio button is already selected/true and it is clicked again to then toggle it to deselected/false and to make that the default behavior for all type="radio" elements in the document? I ask because if the user is on a tablet or a touchscreen, holding down the CTRL key isn't very easy to do.Frustrate
@Frustrate there are at least four approaches to solve the CTRL key issue, see here.Ostrom
By removing the check if(e.ctrlKey) ..., it no longer works, except the first time. I mean we have to press ctrl otherwise it won't work.Reprobative
S
31

Radio buttons are meant to be used in groups, as defined by their sharing the same name attribute. Then clicking on one of them deselects the currently selected one. To allow the user to cancel a “real” selection he has made, you can include a radio button that corresponds to a null choice, like “Do not know” or “No answer”.

If you want a single button that can be checked or unchecked, use a checkbox.

It is possible (but normally not relevant) to uncheck a radio button in JavaScript, simply by setting its checked property to false, e.g.

<input type=radio name=foo id=foo value=var>
<input type=button value="Uncheck" onclick=
"document.getElementById('foo').checked = false">
Syriac answered 4/6, 2012 at 6:13 Comment(2)
what if you want multiple buttons that act as a group while maintaining an unchecked option (or at least the visual appearance of one)? your solution ignores the end user and calls for essentially a rewrite of existing code...Insolvable
A couple years too late, but... then you build one. I've built that UI frequently enough - you set them as checkboxes, and then just bind an event to them, so if you check "none of the above" (or whatever), it unchecks the others, and if you check any of the others, it unchecks that one.Barreto
K
22

This is my answer (though I made it with jQuery but only for the purpose of selecting elements and to add and remove a class, so you can easily replace it with pure JS selectors & pure JS add attribute )

<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>

$(document).on("click", "input[name='radioBtn']", function(){
    thisRadio = $(this);
    if (thisRadio.hasClass("imChecked")) {
        thisRadio.removeClass("imChecked");
        thisRadio.prop('checked', false);
    } else { 
        thisRadio.prop('checked', true);
        thisRadio.addClass("imChecked");
    };
})
Kenna answered 13/1, 2016 at 22:57 Comment(4)
It works for me. Except that when I click on an unchecked radio button to select it, I have to click on it twice so it can be checked. The first click to unchecked the one that is checked, and the second one is to check the one that I want to check :).Bainbridge
Listen, after spending [a lot] of time with this problem at 2 different points+frameworks+implementations, this is [likely] the only feasible answer. Using clicks simply doesn't work because .checked is always true; mousedown doesn't work because mouseup ruins it -- even with e.preventDefault();e.stop[Immediate]Propagation();; the next best technique is the e.ctrlKey approach mentioned above -- but that requires some special knowledge by User. The only way is [likely] using some sort of sentinel such as a class or data-checked. Prove me wrong, please!!!Erleena
it took me about three second to come up with the same (conceptual) answer... made a fiddle to show that it works... i'm sure that pure javascript could be used to do the same thing, just don't want to spend the time to do it... Working ExampleInsolvable
@Erleena challenge accepted, I prove you wrong here - see the bottom of the answer.Ostrom
S
20

How unchecking radio does (not) work

You cannot easily implement uncheck trivially via if(this.checked) this.checked = false, (if you really want to, see the hacker way at the end) because the events fire in this order:

  1. mousedown or keydown
  2. mouseup or keyup
  3. if not checked, set the checked property now
  4. click
  5. input (only if state is changed)
  6. change (only if state is changed)

Now in which event to perform the mentioned uncheck?

  • mouseup or mousedown: then in the step 3 the value is set back to true and change and input event doesn't even fire as the state didn't change when they are called in the sequence - so you can't uncheck it here
  • click: then the state is always false and input and change also doesn't fire - so you can't check it
  • input or change: it doesn't fire when the state is not changed and clicking selected element doesn't change the state - so you can't do anything useful here

The naive way

As you can learn from the sequence above, the way is:

  1. read the previous state in mouseup
  2. set the state in click as negation of previous state

If you want to store the previous state in data attribute, keep in mind that it is saved as string, whereas the checked attribute is boolean. So you can implement it like:

radio.onmouseup = function() { this.dataset.checked = this.checked? 1 : ""; }
radio.onclick = function() { this.checked = !this.dataset.checked; }

It seemingly works, but you should not do this for these reasons:

  • the user may mousedown somewhere else, then hover above radio button, then mouseup: in this case mouseup fires and click does not
  • the user may use Tab to focus radio group, then arrows to change: mouseup doesn't fire and click does

The proper way

There is another issue: dynamically added radio buttons. There are two ways:

  1. element.appendChild(radio) - if you enable deselect on all radios in DOMContentLoaded event, this dynamically added radio is not affected
  2. element.innerHTML+= '<input type="radio">' - effectively replaces the HTML contents of the element and re-creates DOM inside it - so all event listeners are discarded

To solve (2), I recommend onclick content attribute. Note that element.onclick = fn and element.setAttribute("onclick", "fn()") are two different things. Also note that onclick fires everytime the user activates the radio, regardless of the interface he used.

Yet another issue: if you enable deselect, then you should also enable switching by Space to mimic checkboxes behaviour. The following code solves all mentioned issues:

function deselectableRadios(rootElement) {
  if(!rootElement) rootElement = document;
  if(!window.radioChecked) window.radioChecked = {};
  window.radioClick = function(e) {
    const obj = e.target, name = obj.name || "unnamed";
    if(e.keyCode) return obj.checked = e.keyCode!=32;
    obj.checked = window.radioChecked[name] != obj;
    window.radioChecked[name] = obj.checked ? obj : null;
  }
  rootElement.querySelectorAll("input[type='radio']").forEach( radio => {
    radio.setAttribute("onclick", "radioClick(event)");
    radio.setAttribute("onkeyup", "radioClick(event)");
  });
}

deselectableRadios();
<label><input type="radio" name="tag1">one</label>
<label><input type="radio" name="tag1">two</label>
<label><input type="radio" name="tag1">three</label>

<br><br>

<label><input type="radio" name="tag2">one</label>
<label><input type="radio" name="tag2">two</label>
<label><input type="radio" name="tag2">three</label>

Now you can call deselectableRadios() anytime you dynamically add content and calling it on radios multiple times doesn't break it. You can also specify the rootElement to update only a subtree of HTML DOM and make your web faster. If you don't like the global state, you can use the hacker way:

The hacker way

The point is to abuse setTimeout on mouseup to call it after the checked property is set:

function deselectable() {
  setTimeout(checked => this.checked = !checked, 0, this.checked);
}

Now you can make any radio button deselectable:

radio.onmouseup = deselectable;

But this simple one-liner works just with clicking and doesn't solve the issues mentioned above.

The abandoned future

Deselectable radio is basically checkbox where only one in the group can be checked. There was a promising straightforward hope to code it as

<input type="checkbox" name="foo" style="appearance: radio">

However, the radio value is now defined as compat-auto type which is treated like auto, i.e. no visual change. It seems that there will be no progress here in the future.

Skinnydip answered 5/6, 2020 at 9:15 Comment(3)
@JanTuroň, it looks like "The proper way" has a small bug where if you have more than one group of radios, and you select one option on the first group, then click on one option on the second group, then go back and click again on the selected option on the first group, it doesn't get unselected (you need to click it twice to make it unselected).Tonsillitis
@Tonsillitis good catch, pal, thank you. It is fixed and updated with test for two radiobutton groups.Ostrom
Thank YOU @JanTuroň! Now it is working like a charm. I'm using it with 3 radiobutton groups.Tonsillitis
E
16

Wrapped up in a plugin

Limitations:

  1. Require form element
  2. Must trigger click event when changing radio button programmatically

(function($) {
  $.fn.uncheckableRadio = function() {
    var $root = this;
    $root.each(function() {
      var $radio = $(this);
      if ($radio.prop('checked')) {
        $radio.data('checked', true);
      } else {
        $radio.data('checked', false);
      }
        
      $radio.click(function() {
        var $this = $(this);
        if ($this.data('checked')) {
          $this.prop('checked', false);
          $this.data('checked', false);
          $this.trigger('change');
        } else {
          $this.data('checked', true);
          $this.closest('form').find('[name="' + $this.prop('name') + '"]').not($this).data('checked', false);
        }
      });
    });
    return $root;
  };
}(jQuery));

$('[type=radio]').uncheckableRadio();
$('button').click(function() {
  $('[value=V2]').prop('checked', true).trigger('change').trigger('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
  <label><input name="myRadio" type="radio" value="V1" /> R1</label>
  <label><input name="myRadio" type="radio" value="V2" /> R2</label>
  <label><input name="myRadio" type="radio" value="V3" /> R3</label>
  <button type="button">Change R2</button>
</form>
Emmittemmons answered 9/5, 2016 at 4:31 Comment(1)
Excellent, works a treat. We can use a random markup instead of <form> to encapsulate the radio buttons, just change here: $this.closest('form')Daveen
A
10

As radio button mostly used in group, its a lot easier to grab them by getElementsByName( ' ' ); in your script tag. This will return an array, put an event listener on each array child and set the check state. Look at this sample.

var myRadios = document.getElementsByName('subscribe');
var setCheck;
var x = 0;
for(x = 0; x < myRadios.length; x++){

    myRadios[x].onclick = function(){
        if(setCheck != this){
             setCheck = this;
        }else{
            this.checked = false;
            setCheck = null;
    }
    };

}

This guide explain how the code works with a visual demonstration.

Allynallys answered 6/6, 2014 at 18:38 Comment(2)
Super simple and efficient. Thanks.Vern
This script does absolutely nothing. setCheck variable means nothing here.Treece
I
6

while it was asked in terms of javascript, the adaption from jquery is trivial... with this method you can check for the "null" value and pass it...

var checked_val = "null";
$(".no_option").on("click", function(){
  if($(this).val() == checked_val){
    $('input[name=group][value=null]').prop("checked",true);
    checked_val = "null";
  } else {
    checked_val = $(this).val();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="radio" name="group" class="no_option" value="0">option 0<br>
<input type="radio" name="group" class="no_option" value="1">option 1<br>
<input type="radio" name="group" class="no_option" value="2">option 2<br>
<input type="radio" name="group" class="no_option" value="3">option 3<br>
<input type="radio" name="group" class="no_option" value="4">option 4<br>
<input type="radio" name="group" class="no_option" value="5">option 5<br>
<input type="radio" name="group" class="no_option" value="6">option 6<br>
<input type="radio" name="group" class="no_option" value="null" style="display:none">
Insolvable answered 22/10, 2017 at 15:48 Comment(3)
If the adaption is trivial, why not to look inside jQuery code, cut out the relevant parts and implement it in plain javascript as the OP asks? It is not that difficult, look here.Ostrom
it has been addressed in pure javascript--in several different ways, and as noted there is a trivial conversion to pure javascript--this only checks the value of the currently checked item and reacts accordingly...Insolvable
ah, I see, the logic is in the checked_val. What is doing the hidden option in the code then? It also doesn't work well with options having "null" as their value. Why not test === undefined? .val() returns undefined on missing value (unless it is used on select-multiple in which case it may return empty array or null - so the adaptation from jQuery may not be that trivial in general, not your case, of course)Ostrom
D
5

Old question but people keep coming from Google here and OP asked preferably without jQuery, so here is my shot.

Should works even on IE 9

// iterate using Array method for compatibility
Array.prototype.forEach.call(document.querySelectorAll('[type=radio]'), function(radio) {
	radio.addEventListener('click', function(){
		var self = this;
		// get all elements with same name but itself and mark them unchecked
		Array.prototype.filter.call(document.getElementsByName(this.name), function(filterEl) {
			return self !== filterEl;
		}).forEach(function(otherEl) {
			delete otherEl.dataset.check
		})

		// set state based on previous one
		if (this.dataset.hasOwnProperty('check')) {
			this.checked = false
			delete this.dataset.check
		} else {
			this.dataset.check = ''
		}
	}, false)
})
<label><input type="radio" name="foo" value="1"/>foo = 1</label><br/>
<label><input type="radio" name="foo" value="2"/>foo = 2</label><br/>
<label><input type="radio" name="foo" value="3"/>foo = 3</label><br/>
<br/>
<label><input type="radio" name="bar" value="1"/>bar = 1</label><br/>
<label><input type="radio" name="bar" value="2"/>bar = 2</label><br/>
<label><input type="radio" name="bar" value="3"/>bar = 3</label><br/>
Doris answered 14/8, 2019 at 1:32 Comment(0)
B
3

I came here because I had the same issue. I wanted to present the options to the user while leaving the option of remaining empty. Although this is possible to explicitly code using checkboxes that would complicate the back end.

Having the user Control+click is almost as good as having them uncheck it through the console. Catching the mousedown is to early and onclick is too late.

Well, at last here is a solution! Just put these few lines once on the page and you have it made for all radio buttons on the page. You can even fiddle with the selector to customize it.

window.onload = function() {
  document.querySelectorAll("INPUT[type='radio']").forEach(function(rd) {
    rd.addEventListener("mousedown", function() {
      if(this.checked) {
        this.onclick=function() {
          this.checked=false
        }
      } else {
        this.onclick=null
      }
    })
  })
}
<input type=radio name=unchecksample> Number One<br>
<input type=radio name=unchecksample> Number Two<br>
<input type=radio name=unchecksample> Number Three<br>
<input type=radio name=unchecksample> Number Four<br>
<input type=radio name=unchecksample> Number Five<br>
Bargeman answered 8/3, 2017 at 7:51 Comment(0)
T
2

That's what I came to:

function uncheck_radio_before_click(radio) {
    if(radio.prop('checked'))
        radio.one('click', function(){ radio.prop('checked', false); } );
}
$('body').on('mouseup', 'input[type="radio"]', function(){
    var radio=$(this);
    uncheck_radio_before_click(radio);
})
$('body').on('mouseup', 'label', function(){
    var label=$(this);
    var radio;
    if(label.attr('for'))
        radio=$('#'+label.attr('for')).filter('input[type="radio"]');
    else
        radio=label.children('input[type="radio"]');
    if(radio.length)
        uncheck_radio_before_click(radio);
})

http://jsfiddle.net/24vft2of/2/

Tedie answered 23/4, 2015 at 20:12 Comment(0)
P
2

In the radio button object creation code include these three lines:

  obj.check2 = false;    // add 'check2', a user-defined object property
  obj.onmouseup = function() { this.check2 = this.checked };
  obj.onclick = function() { this.checked = !this.check2 };
Pitiful answered 11/5, 2018 at 8:14 Comment(0)
B
2

Full example in pure JavaScript :

box.onmouseup = function() {
  var temp = this.children[0];
  if (temp.checked) {
    setTimeout(function() {
      temp.checked = false;
    }, 0);
  }
}
<label id='box' style='margin-right: 1em;'>
  <input type='radio' name='chk_préf_méd_perso' value='valeur'>
  libellé
</label>
Bustup answered 19/7, 2019 at 13:33 Comment(1)
Simple and straightforward. Thanks!Philae
E
2

I'm surprised no-one has posted this "neat trick" version which doesn't use any JavaScript, it only uses CSS.

#radio1 {
    display: none;
}

#wrapper {
    /* NOTE: This wrapper div is not needed provided you can position the label for #radio1 on top of #radio2 using some other technique. */
    position: relative;
}

#radio1:not(:checked) ~ * label[for="radio1"] {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}
#radio1:checked ~ * label[for="radio1"] {
    display: none;
}

/* Non-essential styles: */ 

label[for],
label:not([for="radio1"]) {
    cursor: pointer;
    border-radius: 7px;
}
label[for]:hover + label,
label:not([for="radio1"]):hover {
    background-color: #ccc;
}
<input type="radio" name="group1" id="radio1" checked="checked"  />

<p>Look mum, <strong>no JavaScript!</strong></p>

<div id="wrapper">
    <label for="radio1"></label>
    <label>
        <input type="radio" name="group1" id="radio2" />
        You can toggle me on and off!
    </label>
</div>

Explanation:

  • #radio1 (<input type="radio" id="radio2" />) is always hidden.
  • Using CSS's :checked and :not(:checked) pseudo-class selectors with sibling selectors (+ and ~) allow other elements' style to be affected depending on whether or not an <input type="checkbox" /> or <input type="radio" /> is checked.
    • So when #radio1 is un-checked (or when #radio2 is checked) that causes a <label> to be overlayed on-top of #radio2 and that label has for="radio1", so clicking it will cause #radio1 to be checked, not #radio2.
    • IMPORTANT CAVEAT: CSS's sibling selector rules only allows selectors to select elements based on their ancestors and their ancestors earlier siblings. So you cannot style an element based on any other descendants of its ancestors.
      • This limitation will be removed when CSS4's :has() selector function is supported but as of November 2020 only PrinceXML supports :has() and it's currently looking like :has() will be dropped from CSS4 entirely owing to the difficulty of implementation.

This approach can be scaled to support multiple radio buttons:

#uncheckAll {
    display: none;
}

#uncheckAll:checked ~ * label[for="uncheckAll"] {
    display: none;
}

label {
    cursor: pointer;
}

label:not([for]) {
    position: relative;
}

label[for="uncheckAll"] {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

input[name="group1"]:not(:checked) + label[for="uncheckAll"] {
    display: none;
}
<input type="radio" name="group1" id="uncheckAll" checked="checked"  />

<label>
    <input type="radio" name="group1" id="radio2" />
    <label for="uncheckAll"></label>
    You can toggle me on and off!
</label>

<label>
    <input type="radio" name="group1" id="radio3" />
    <label for="uncheckAll"></label>
    And me!
</label>

<label>
    <input type="radio" name="group1" id="aragorn" />
    <label for="uncheckAll"></label>
    And my sword!
</label>

<label>
    <input type="radio" name="group1" id="gimli" />
    <label for="uncheckAll"></label>
    And my axe!
</label>
Edik answered 25/11, 2020 at 10:59 Comment(0)
C
1

Extending user3716078's answer to allow multiple independent radio button groups and a neater way of assigning event listeners to multiple elements...

window.onload = function() {

    var acc_checked=[];

    [].slice.call(document.querySelectorAll('.accordion input[type="radio"]')).forEach(function(el,i){
        /**
         * i represents the integer value of where we are in the loop
         * el represents the element in question in the current loop
         */
        el.addEventListener('click', function(e){

            if(acc_checked[this.name] != this) {
                acc_checked[this.name] = this;
            } else {
                this.checked = false;
                acc_checked[this.name] = null;
            }

        }, false);

    });

}
Cutaneous answered 15/6, 2016 at 16:31 Comment(0)
S
1

I will try to make a small answer with 3 radio buttons, you can add stuff later on.

const radios = Array.from(document.getElementsByClassName('radio'))

for(let i of radios) {
    i.state = false

    i.onclick = () => {
        i.checked = i.state = !i.state

        for(let j of radios)
            if(j !== i) j.checked = j.state = false
    }
}
<input class="radio" type="radio">X
<input class="radio" type="radio">Y
<input class="radio" type="radio">Z
This works for single form. If you have multiple form with the class="radio", then once you click on a radio button, the others are disabled. Use this if that's what you want.

Now I wanted to implement this on my rails project, which has multiple forms (depends, fetched from database), each form has 2 visible radio buttons + 1 hidden radio button.

I want the user the select / deselect the radio button of each form. And selecting one on a form shouldn't deselect the other selected button on another form. So I rather did this:

var radios = Array.from(document.getElementsByClassName('radio'))

for (let i of radios) {
  i.state = false

  i.onclick = () => {
    i.checked = i.state = !i.state

    for (let j of radios)
      if (j !== i) j.state = false
  }
}
<form>
  <input class="radio" name="A" type="radio">A
  <input class="radio" name="A" type="radio">B
  <input class="radio" name="A" type="radio">C
</form>

<form>
  <input class="radio" name="A" type="radio">D
  <input class="radio" name="A" type="radio">E
  <input class="radio" name="A" type="radio">F
</form>

<form>
  <input class="radio" name="SOMETHING" type="radio">G
  <input class="radio" name="SOMETHING" type="radio">H
  <input class="radio" name="SOMETHING" type="radio">I
</form>

You see all have the same name, but they are in a different forms, grouped by 3, so this works for multiple forms.

Swain answered 24/7, 2020 at 2:14 Comment(0)
D
1

I know It's very late (even unnecessary now) and there are many solutions here, but I couldn't find any specific to the question asked or there is so much code in them for this simple scenario, one can easily ignore it while looking for an answer.

So here, I am proposing my solution as It might help any newcomer. The idea is simple, just

  • Set the same class on required toggles in my case its "toggles"
  • Get the current value of the toggle on mouse hover action
  • Inverse the toggle value.

By this either you can select any of the toggles or completely ignores them but clicking again on the already selected toggle. You can also test this with the given snippet.

var val;
$('.toggles').mouseup(function(){
  val = this.checked
}).click(function(){
  this.checked = val == true ? false : true
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
    <input class="toggles form-check-input" type="radio" value="true" name="enabled" id="enabled_true">
    <label class="form-check-label" for="enabled_true">Enabled</label>
    <input class="toggles form-check-input" type="radio" value="false" name="enabled" id="enabled_false">
    <label class="form-check-label" for="enabled_false">Disabled</label>
</div>
Despond answered 23/7, 2021 at 20:53 Comment(0)
C
1

This javascript facilitates deselection for each radio in the document:

function toggleRadio(event)
{
    if(event.target.type === 'radio' && event.target.checked === true)
    {
        setTimeout(()=>{ event.target.checked = false; },0);
    }
}
document.addEventListener('mouseup', toggleRadio);
body { font-size: .55em; }
table { border-collapse: collapse; margin: 0 auto; }
td, th { border: 1px solid #333333; }
td:first-child { padding: 0 0.7em; }
#scale { font-weight:bold; text-align:center; }
<p id="scale">
  5 = Excellent | 4 = Satisfactory | 3 = About Average | 2 = Unsatisfactory | 1 = Very Poor
</p>
<table>
  <thead>
    <tr>
      <th>&nbsp;</th> <th>5</th> <th>4</th> <th>3</th> <th>2</th> <th>1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>How do rate the default behavior of radios inputs in HTML?</td>
      <td><input type="radio" name="r1" value="5" required></td>
      <td><input type="radio" name="r1" value="4"></td>
      <td><input type="radio" name="r1" value="3"></td>
      <td><input type="radio" name="r1" value="2"></td>
      <td><input type="radio" name="r1" value="1"></td>
    </tr>
    <tr>
      <td>How do rate this code's ability to deselect radios?</td>
      <td><input type="radio" name="r2" value="5" required></td>
      <td><input type="radio" name="r2" value="4"></td>
      <td><input type="radio" name="r2" value="3"></td>
      <td><input type="radio" name="r2" value="2"></td>
      <td><input type="radio" name="r2" value="1"></td>
    </tr>
  </tbody>
</table>

Advatages of this approach:

  1. Deselection is achieved by clicking the currently selected radio.
  2. Code doesn't require any DOM searches to acquire the radio elements.
  3. Radio inputs that are programmatically added to the document, after page-load, will also be deselect-able.
  4. Only one event listener is created to service all radios (instead of one for each radio).
  5. Code can be ran before or after page load and it still works the same.

User experience considerations, of this code, are discussed here.

Consistory answered 10/9, 2021 at 19:0 Comment(5)
I'm not fluent in javascript. Why do you need to setTimeout? Why can't you just event.target.checked = false;Buckhound
@Buckhound : Deselection doesn't work without that timeout there. I think this is because the browser's default behavior is to always set a radio to true when you click it. If you set it to false too early, it will just set it right back to true afterwards. However, if you wait until the next event loop cycle (which is what this zero millisecond setTimeout accomplishes) you end up setting it to false AFTER the "automatic setting to true" occurs.Consistory
Thanks @Lonnie. Makes sense. This seems to work well.Buckhound
Would there be a way to add also the label of the radio button to the script? That is, if you click the label of a checked radio button, that would also uncheck the radio button. I can't figure out how to implement the second part of the if clause (event.target.checked === true) for the label.Buckhound
@Buckhound : Sure. Take a look at this.Consistory
C
0

Most of the modern day browsers consider checked="anything" as checked="true".

You might have to remove the checked attribute if that makes sense in your case, one of which might be related to when you load the page.

$(this).removeAttr('checked')

This might help you in cases when you want your radio button to be checked adhering to some condition. You can simply remove the attribute to achieve that.

PS: Not helpful in all the cases.

Combatant answered 2/11, 2020 at 16:41 Comment(0)
K
0

Here is the way for plain JS, which onchange and onclick events are combined (onchange for checking while onclick for unchecking).

document.querySelector("input").onchange = function() {
    this.onclick = function() {
        this.checked = false;
        this.onclick = null;
    }
};
Kellam answered 6/11, 2020 at 11:7 Comment(0)
H
0

If you are looking for solution in jQuery here it is. It is similar to this

    $('input:radio').click(function() { 
      let name = $(this).attr('name');
      let self = $(this);
      [].filter.call($(`input[name=${name}]`), function(ele){
        return self[0] !== $(ele)[0];
      }).forEach(function(otherEle){
        $(otherEle).removeAttr('data-check');
      });

      if($(this).attr('data-check')){
        $(this).prop("checked", false);
        $(this).removeAttr('data-check');
      }else{
        $(this).attr("data-check", "1");
      }
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
  <input class="radio" name="A" type="radio">A
  <input class="radio" name="A" type="radio">B
  <input class="radio" name="A" type="radio">C
</form>

<form>
  <input class="radio" name="B" type="radio">D
  <input class="radio" name="B" type="radio">E
  <input class="radio" name="B" type="radio">F
</form>

<form>
  <input class="radio" name="C" type="radio">G
  <input class="radio" name="C" type="radio">H
  <input class="radio" name="C" type="radio">I
</form>
Hie answered 18/11, 2020 at 7:53 Comment(0)
W
0

I had this issue and my solution was rather simple, I just made them into checkboxes and when one checkbox was toggled, I deselected all the other checkboxes in the group.

I know it is a bit hacky, and has a large big O complexity (although n is small), but it works! (todo: think of more original names for variables)

$(document).ready(function() {
  $("input[name=days]").each((_, el) => {
    el.addEventListener("click", function () {
      $("input[name=days]").each((_, myEl) => {
        if (el != myEl) {
          myEl.checked = false;
        }
      });
      // Do other stuff
    });
  });
});
.radio-selector {
  display: inline-flex;
  flex-wrap: wrap;
  vertical-align: top;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  border: 0;
}
.radio-selector input {
  position: absolute !important;
  clip: rect(0, 0, 0, 0);
}
.radio-selector label {
  margin: 0 1rem 1rem 0;
  padding: 0.75rem 1rem;
  min-width: 10rem;
  font-size: 1.6rem;
  border-radius: 2rem;
  text-align: center;
  color: #333;
  border: 1px solid #333;
  transition: all 0.3s ease-in-out;
}
.radio-selector label:hover {
  background-color: lightpink;
  cursor: pointer;
}
.radio-selector input:checked + label {
  color: white;
  background-color: purple;
  border: 1px solid transparent;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<fieldset class="radio-selector">
  <input type="checkbox" id="day-1" name="days" value="1" />
  <label for=day-1 class="radio-btn">+- 1 day</label>
  <input type="checkbox" id="day-3" name="days" value="3" />
  <label for=day-3 class="radio-btn">+- 3 days</label>
  <input type="checkbox" id="day-7" name="days" value="7" />
  <label for=day-7 class="radio-btn">+- 7 days</label>
</fieldset>
Washboard answered 15/9, 2021 at 10:18 Comment(0)
O
0

sorry if my answer is already answered but honestly i read them all very quickly because there are so many

i am not so skilled, but i think i found a VERY SIMPLE way to uncheck an already checked radio button just by click it again... just with a global var, a little function, and onclick event

<script>
  var lastChecked = null;

  function unckeck(myRadio)
  {
    if ( lastChecked == myRadio )
    {
      lastChecked = null;
      myRadio.checked = false;
    }
    else
      lastChecked = myRadio;
  }
</script>

<form>
  <input type='radio' name='someCommonName' value='foo' onclick='uncheck(this)'/> foo <br/>
  <input type='radio' name='someCommonName' value='bar' onclick='uncheck(this)'/> bar <br/>
  <input type='radio' name='someCommonName' value='baz' onclick='uncheck(this)'/> baz <br/>
</form>
Obligee answered 6/3, 2022 at 4:35 Comment(0)
C
-1

You could use the checked property of a radio button to uncheck it.

Something like this:

<script>
 function uncheck()
 {
  document.getElementById('myRadio').checked = false;        
 }
 function check()
 {
  document.getElementById('myRadio').checked = true;        
 }
</script>
<input id="myRadio" type="radio" checked="checked"/>
<button onclick="uncheck();">Uncheck</button>
<button onclick="check();">Check</button>

​See it in action here: http://jsfiddle.net/wgYNa/

Clevelandclevenger answered 4/6, 2012 at 6:16 Comment(0)
P
-1

The full code will look something like this

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>

<body>
<input name="radio" type="radio" id="myRadio" value="myRadio" checked="checked"     onclick="setRadio(this)" />
<label for="myRadio"></label>


<script language="javascript">
function setRadio(obj) 
{
    obj.checked = false;
}
</script>
</body>
</html>
Phore answered 4/6, 2012 at 6:25 Comment(0)
P
-1

Here's an example of where it is arguably appropriate to uncheck radio buttons other than by making a new selection. I have a dictionary whose entries can be selected using a variety of indices. Which index to use is selected by means of a set of radio buttons. However, there is also a "random entry" button that the user can use if he or she just wants to browse. Leaving an index in place when the entry has been selected by means of the random entry button would be misleading, so when this button is pressed, I uncheck all of the index selection radio buttons and replace the contents of the index frame with an empty page.

Prescriptive answered 18/3, 2013 at 17:1 Comment(1)
Or really, anytime the radios are not required="required". Otherwise, you either have to send a value off to the server and assume that every user has thought well & hard about interacting with that radio-group and the potential repercussions of what the server might do -- or provide a radio button for I selected an option, and then realized I don't care, but since radios can't be unchecked then this is the only option I'm left with. Or a Web 1.0 reset.Erleena
A
-1

If you use Iclick pluging, it is as simply as you see below.

 $('#radio1').iCheck('uncheck');
Angelita answered 12/1, 2018 at 15:53 Comment(1)
to uncheck radio button for implement plugin hell nahDeception
B
-1

Unfortunately it does not work in Chrome or Edge, but it does work in FireFox:

$(document)
// uncheck it when clicked
.on("click","input[type='radio']", function(){ $(this).prop("checked",false); })
// re-check it if value is changed to this input
.on("change","input[type='radio']", function(){ $(this).prop("checked",true); });
Brote answered 24/9, 2018 at 20:3 Comment(0)
C
-1

A working bug free update to Shmili Breuer answer.

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

        // update and remove the previous checked class
        var $prevChecked = $('input[name=' + $this.attr('name') + ']:not(:checked).checked');
            $prevChecked.removeClass('checked');

        if( $this.hasClass("checked") ) {
            $this.removeClass("checked");
            $this.prop("checked", false);
        }
        else {
            $this.addClass("checked");
        }
    });
})();
Calesta answered 22/8, 2019 at 8:52 Comment(0)
S
-1

This almost worked for me.

<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>

$(document).on("click", "input[name='radioBtn']", function(){
    thisRadio = $(this);
    if (thisRadio.hasClass("imChecked")) {
        thisRadio.removeClass("imChecked");
        thisRadio.prop('checked', false);
    } else { 
        thisRadio.prop('checked', true);
        thisRadio.addClass("imChecked");
    };
})

But If I check a radio button, then check another and try to check the first one again I must do two clicks. This is because it has the class imChecked. I just needed to uncheck the other radio buttons before the verification.

Add this line makes it work:

$("input[name='radioBtn']").not(thisRadio).removeClass("imChecked");

<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>
<input type='radio' name='radioBtn'>

$(document).on("click", "input[name='radioBtn']", function(){
    thisRadio = $(this);
    $("input[name='radioBtn']").not(thisRadio).removeClass("imChecked");
    if (thisRadio.hasClass("imChecked")) {
        thisRadio.removeClass("imChecked");
        thisRadio.prop('checked', false);
    } else { 
        thisRadio.prop('checked', true);
        thisRadio.addClass("imChecked");
    };
})
Sumac answered 1/4, 2020 at 7:30 Comment(0)
J
-1

The code below will do the trick.

$('input[type=radio]').click(function() {
        if($(this).hasClass("checked")){
            this.checked = false;
            $(this).removeClass("checked")
        }else{
            $(this).addClass("checked")
        }
    });
Jerad answered 9/5, 2020 at 10:11 Comment(0)
L
-1

Let's suppose you have a button where on clicking it, you can make all your radio button selection to false. You can write the below code inside the onclick handler.
Below code take radio buttons based on class name and for each element it will mark it to false.

var elements=document.getElementsByClassName('Button');

Array.prototype.forEach.call(elements, function(element) {
  element.checked = false;
});
Lelahleland answered 3/6, 2020 at 5:30 Comment(2)
Can you add some explanation to your anwer?Souterrain
Added the explanation!Lelahleland

© 2022 - 2024 — McMap. All rights reserved.