nickpish
nickpish

Reputation: 847

Loop through checkboxes and conditionally disable unchecked

I'm trying to write a basic function in pure JS that simply checks the number of checked checkboxes, and if that number exceeds a certain amount, disables the rest. I can achieve this easily in jQuery, but trying to get it working in pure JS. I have a CodePen set up here and I'm including my working JS below. Thanks for any insight here.

(function() {

  var checkboxes = document.querySelectorAll('input[id^="mktoCheckbox"]');
  var active = document.querySelectorAll('input[id^="mktoCheckbox"]:checked');
  var numActive = active.length;

  console.log(numActive);

  if (numActive > 1) {
    for(var i = 0; i < checkboxes.length; i++){
            if (checkboxes[i].checked == true) {
                return;
            } else {
                checkboxes[i].disabled == true;
            }
        }
  }

})();

Upvotes: 1

Views: 2431

Answers (2)

FK82
FK82

Reputation: 5075

Here's a working pen.

First of all, imo, you should use getAttribute and setAttribute on DOM elements. HTMLInputElement.checked afaik only reflects the checked attribute (and converts it to boolean) for convenience.

With that in mind, you need to now test against strings with the strict comparison operator ===. E.g.

if(checkbox.getAttribute('checked') === 'true') {...}

since using == would evaluate to false

true == 'true' // false

Also, instead of the for loop you can make use the for-of loop on DOM collections. I.e. this works:

const checkboxes = document.querySelectorAll('...');
for(const checkbox of checkboxes) {
    ...
}

Keep in mind that you use continue and break to control the loop and not return.

Upvotes: 1

31piy
31piy

Reputation: 23869

There are two problems in your code:

  1. You're returning from the if condition, which causes the loop to terminate.
  2. You're not assigning true to disabled attribute, instead you're comparing with ==.

Change the related snippet to the following to make it work:

if (numActive > 1) {
  for (var i = 0; i < checkboxes.length; i++) {
    if (checkboxes[i].checked != true) {
      checkboxes[i].disabled = true;
    }
  }
}

You can find a working fork of your pen here. Following is a working SO snippet:

(function() {
  var checkboxes = document.querySelectorAll('input[id^="mktoCheckbox"]');
  var active = document.querySelectorAll('input[id^="mktoCheckbox"]:checked');
  var numActive = active.length;

  console.log(numActive);

  if (numActive > 1) {
    for (var i = 0; i < checkboxes.length; i++) {
      if (checkboxes[i].checked != true) {
        checkboxes[i].disabled = true;
      }
    }
  }
})();
<fieldset>
  <legend>Choose some monster features</legend>

  <div>
    <input type="checkbox" id="mktoCheckbox_1" name="feature" value="scales" checked />
    <label for="scales">Scales</label>
  </div>

  <div>
    <input type="checkbox" id="mktoCheckbox_2" name="feature" value="horns" />
    <label for="horns">Horns</label>
  </div>

  <div>
    <input type="checkbox" id="mktoCheckbox_3" name="feature" value="claws" />
    <label for="claws">Claws</label>
  </div>

  <div>
    <input type="checkbox" id="mktoCheckbox_4" name="feature" value="tails" checked />
    <label for="tails">Tails</label>
  </div>

</fieldset>

Upvotes: 3

Related Questions