16

I had this working, but I didnt save and cannot replicate. I am trying to toggle checkboxes using if else. What am I doing wrong.

What I thought would work:

function myForm() {
    var inputs = document.getElementsByTagName("input");
    for(var i = 0; i < inputs.length; i++) {
        if(inputs[i].type == "checkbox") { 
            if(inputs[i].checked = false) {
                inputs[i].checked = true; 
            } else {
                if(inputs[i].checked = true) {
                    inputs[i].checked = false; 
                }   
            }
        }  
    } 
}
Kervvv
  • 751
  • 4
  • 14
  • 27

5 Answers5

76

It can be easier:

inputs[i].checked = !inputs[i].checked;
Ali Seyfollahi
  • 2,662
  • 2
  • 21
  • 29
37

How about using an operator, that is defined to toggle booleans using 1 as second operand?

inputs[i].checked ^= 1;

This uses the XOR Compound assigment operator, and it toggles booleans because ¬A ≡ A ^ 1.

It also doesn't require looking up inputs[i] a second time.

2020 update: You can also eliminate the for loop and all those vars by using the forEach function to iterate over the checkboxes, reducing your function body to:

document.querySelectorAll('input[type="checkbox"]').forEach(e => e.checked ^= 1);
Alex Stragies
  • 552
  • 6
  • 12
  • 4
    Whoa! Never seen that before. What is that operator ^=? – Tom Rossi Dec 20 '18 at 20:50
  • 4
    `^` is the XOR operator; `a ^ b` is true if `a` and `b` have different values, or false otherwise. `a ^= true` (equivalent to `a = a ^ true`) evaluates to `false` if `a` is `true` and `true` if `a` is `false`. – Benjamin Carlsson Feb 08 '19 at 23:17
  • 9
    While this "works", I don't think it's a good idea - using bitwise operators when not needed makes for less readable, more opaque code, as you can see by the first comment. It will confuse people. Readable code is more important than concise code, unless you're code golfing. – Snow May 09 '19 at 06:28
  • 2
    I disagree. Back in the day XOR was covered in the first week of CS. If "XOR 1" is "opaque" or "unreadable" to a non-beginner programmer, they should probably never go near any kind of performance, or security critical code. – Alex Stragies May 09 '19 at 09:48
7

Single equals is assignment, double/triple equals is for equality. You need to use double or triple equals in your if/else block.

    if(inputs[i].checked == false) {
        inputs[i].checked = true; 
    }
    else {
        if(inputs[i].checked == true) {
            inputs[i].checked = false; 
         }   
    }
IrkenInvader
  • 4,030
  • 1
  • 12
  • 23
  • 1
    It is a good practice to always use `===`/`!==` instead of `==`/`!=` when comparing to `Boolean`, or to perform type coercion manually only when you need to. – Farside May 17 '16 at 21:47
  • 4
    In fact, the if statement inside the else statement is completely unnecessary. Just do `inputs[i].checked = false;` inside the else. – Luke3butler May 17 '16 at 21:49
  • 1
    @Farside In this case they might as well use `==` to save bytes, because `checked` will always be a boolean. But yes, it is good practice. – 4castle May 17 '16 at 21:49
  • I was actually planning on using triple equal as I wrote the opening sentence...not sure what happened. – IrkenInvader May 17 '16 at 21:53
  • Thank you. All of my checkboxes are toggling, except for the checkbox that initiates the toggling. – Kervvv May 17 '16 at 21:56
  • @ceuskervin That's because it's being toggled twice. Once by the click, and once by your code. Whatever code is capturing the checkbox click event needs to `return false` or use `e.preventDefault`. – 4castle May 17 '16 at 22:03
  • Couldn't you just say `inputs[i].checked = !(inputs[i].checked)` instead of using the `if`/`else`? – AvahW Nov 03 '17 at 11:12
  • Yeah that should work well, this answer was more to show op why his code didn't work. – IrkenInvader Nov 03 '17 at 14:24
0

Another correct answer could be:

inputs[i].checked = input.checked ? false : true;
0

I thought I would add to this since it led me to an answer I was seeking for checking all checkboxes with bookmarklet. Using the bitwise operator worked like a charm in IE 11 and Chrome. Haven't tried it in other browsers.

javascript:(function(){var chbxs=document.querySelectorAll('input');for(i in chbxs){chbxs[i].checked^=1;}})();