0

I'm having an issue with radio inputs and controlling them through JavaScript. The problem I have is with evaluating whether an input is checked when the click event fires.

const radio = document.querySelector('input[type="radio"]');

radio.addEventListener('click', (e) => {
  console.log(e.target.checked);
  console.log(e)
  if(e.target.checked){
    e.target.checked = false;
  }
});
<label for="radio">Click me to trigger event</label><input type="radio" id="radio" name="radio">
<label for="radio2">Click me to switch back</label><input type="radio" id="radio2" name="radio">

This shows how if you trigger the event, there is a mismatch between the e.target.checked value and if you inspect the MouseEvent object in the browser console (navigate to the target and the checked property). When you compare the two, the former always appear to be true (even when visually you can see the input is not checked) and the latter is false.

Why are the two properties not the same? Any help will be appreciated.

Jonas
  • 121,568
  • 97
  • 310
  • 388
dafoxuk
  • 439
  • 3
  • 8
  • Just a comment providing some context: I'm trying to control the radio buttons using JS because I'm building a CSS-only accordion but where if JS is enabled it provides the additional ability to toggle an open accordion. Thanks. – dafoxuk Jun 14 '19 at 08:34
  • Please put your runnable example **here, on-site** using Stack Snippets (the `[<>]` toolbar button; [here's how to do one](https://meta.stackoverflow.com/questions/358992/)). – T.J. Crowder Jun 14 '19 at 08:35
  • 1
    See the linked question's answers. When you expand the logged event object, you're seeing it's state *as of when you expanded it*, not as of when you logged it. Your code is setting `checked` to `false`, so you see `false` in the expanded version. – T.J. Crowder Jun 14 '19 at 08:38
  • Thanks @T.J.Crowder - very helpful, esp in regards to the logging of the event. Follow-up question, why is `console.log(e.target.checked)` always true (even if using `e.preventDefault`)? – dafoxuk Jun 14 '19 at 08:56
  • 1
    The radio button is checked and then the `click` event fires. If you use `preventDefault` the previous state of the radio button set is restored once all the handlers are run. (Similarly with checkboxes, the checkbox is toggled, then the `click` event fires, then if you use `preventDeafult` the checkbox's previous state is restored.) This might seem odd (usually the default is after the event), but imagine the mess if people had to figure out what the new state *would be* (if they didn't prevent the default) in the handler. They'd constantly get their checkboxes and radio buttons wrong. :-) – T.J. Crowder Jun 14 '19 at 09:06
  • @T.J.Crowder, again very helpful. The solution I went with in the end was to use a custom attribute to keep track of whether the radio was checked or not. Works well - thanks for your help. – dafoxuk Jun 14 '19 at 14:50
  • No worries! That's an unusual thing to do, why do you need that? (Just curious.) – T.J. Crowder Jun 14 '19 at 14:52
  • I'm making a CSS-only accordion (aka drawers), but wanted to be able to toggle the accordion when JavaScript is enabled - one of those things that should have taken a few minutes, but then got stuck on something that didn't seem to make sense! – dafoxuk Jun 14 '19 at 15:01

0 Answers0