'How can I toggle an element's attributes using pure JavaScript?

Most of the similar questions that arose as I wrote this one were like this (where the user wishes to toggle an element's class using pure JS) or this (where the user wishes wishes to toggle other attributes using jQuery)

My question is a mixture of the two. I am aware that the el.classList.toggle() method exists for toggling an element's class using pure JS, but I wish to toggle different attributes using pure JS, specifically the checked attribute of some radio buttons, since this (annoyingly) does not change when different options are selected.

Is it possible to toggle the checked attribute on my two radio buttons with pure JS (by toggling I mean remove the attribute from the element altogether if it is present, and add it if it is not)?

radios = document.getElementsByName("Floor");
for (i = 0; i < radios.length; i++) {
    radios[i].addEventListener('change', function () {
        this.(/*checked attribute*/).toggle()
    }, false);
}
<input checked id="Floor" name="Floor" type="radio" value="0">Ground Floor
<input id="Floor" name="Floor" type="radio" value="1">First Floor

Edit: The possible duplicate question mentioned in the comments does not quite solve my problem. I don't need to change which radio button appears checked, I just want to toggle the checked attribute, to make it easier for me to reference the button that is checked later on in the code. Of course, if there is another, easier way of doing this, I'm all ears.



Solution 1:[1]

There actually is an Element.toggleAttribute method for boolean attributes. MDN Docs.

However, since it is not supported in IE, you might want to add the MDN Polyfill

Solution 2:[2]

there is no toggle method for attribute.

You can use:

elm[elm.hasAttribute('hidden')?'removeAttribute':'setAttribute']('hidden', '')

or

elm.hasAttribute('hidden') ? removeAttribute('hidden') : setAttribute('hidden')

EDIT: there is now toggle method for attribute.

elm.toggleAttribute('hidden')

https://developer.mozilla.org/docs/Web/API/Element/hasAttribute

Solution 3:[3]

I didn't test this, but this should do the trick.

radios = document.getElementsByName("Floor");
  for (i = 0; i < radios.length; i++) {
    radios[i].addEventListener('change', function () {
       if ( this.checked ) {
          this.setAttribute("checked", "false");
       } else {
          this.setAttribute("checked", "true");
       }
  }, false);
}

Solution 4:[4]

This will work definitely well

const attrToggle = (el, attr) => el.getAttribute(attr) == 'false' ? el.setAttribute(attr, "true") : el.setAttribute(
      attr, "false")

It's similar to native toggleAttribute.

Solution 5:[5]

Element.toggleAttribute(name) used to toggle boolean attribute https://developer.mozilla.org/en-US/docs/Web/API/Element/toggleAttribute

this.toggleAttribute("checked");

Solution 6:[6]

To anyone stumbling on this question, no one in comments or answers since 2017 seems to have pick up on the OP's incorrect assumptions on the true nature of the checked element attribute they are trying to 'toggle'. As this post has so far been viewed 19k times, here is the information you might actually be looking for:

<input type="radio" checked>

In this context the element's checked attribute is a flag developers can use to tell the browser to render a "checked" state on a radio or checkbox input on page load. After page load, the browser does not update or toggle this attribute when a user later selects or un-selects the input.

From MDN:

Checked: A Boolean attribute which, if present, indicates that this radio button is the default selected one in the group.

Therefore the approach of using Element.toggleAttribute('checked') suggested by some here, won't work as expected as the .toggleAttribute() method adds or removes the pre-render flag from the input, but doesn't update the element's 'checked' state as the OP is trying to do. Applying a boolean value to the attribute also has no effect on the state of the element: (this wont work) checked="false"

In JavaScript you can access the current state of an input through HTMLInputElement's IDL boolean property .checked, not to be confused with the Element attribute by the same name referenced by the OP. Here HTMLInputElement.checked is both a getter and setter, meaning you can access (and toggle the value of) .checked as follows:

<input type="radio" id="spam-machine" class="blackhat" name="spam-me" value="sure!">

<script>
    const spamMe = document.querySelector('#spam-machine');
    spamMe.checked = !spamMe.checked;
</script>

You can additionally selectively style checked inputs using the :checked CSS pseudo class:

input[type="radio"].blackhat:checked { visibility: hidden; }

Now go forth into the world .... rendering to no one evil for evil.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Nicolay Hekkens
Solution 4 Richard-Degenne
Solution 5 karel
Solution 6