Javascript add event listers for all checkboxes inside a class

Viewed 2397

I am trying to add event listers for all checkboxes inside a class. I am able to add event listener to class. How can I add to all checkboxes inside that class?

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

for (var i = 0; i < classname.length; i++) {
    classname[i].addEventListener('click', myFunction, false);
}
4 Answers

You could use querySelectorAll

const checkboxes = document.querySelectorAll( '.example input[type=checkbox]' );

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    console.log( attribute );
};

for (var i = 0; i < checkboxes.length; i++) {
    checkboxes[i].addEventListener('click', myFunction, false);
}
<div class="example">
  <input type="checkbox" data-myattribute="1" />
  <input type="checkbox" data-myattribute="2" />
</div>


Or you could just use the event.target property of your old event listener like this:

var classname = document.getElementsByClassName("example");

var myFunction = function(event) {
  var attribute = event.target.getAttribute("data-myattribute");
  console.log(attribute);
};

for (var i = 0; i < classname.length; i++) {
  classname[i].addEventListener('click', myFunction, false);
}
<div class="example">
  <input type="checkbox" data-myattribute="1" />
  <input type="checkbox" data-myattribute="2" />
</div>

Of course, with the second approach you need to check, if you really deal with a checkbox.


In your case though I would rather use change events instead of click. That way, you can use it within a label and have the label clickable, instead of only the checkbox itself.

const checkboxes = document.querySelectorAll( '.example input[type=checkbox]' );

var myFunction = function( event ) {
    var attribute = event.target.getAttribute("data-myattribute");
    console.log( attribute );
};

for (var i = 0; i < checkboxes.length; i++) {
    checkboxes[i].addEventListener('change', myFunction, false);
}
<div class="example">
  <label>
    <input type="checkbox" data-myattribute="1" /> test1
  </label>
  <label>
    <input type="checkbox" data-myattribute="2" /> test2
  </label>
</div>

Since JS events bubble up to parent elements you only have to attach ONE event listener to the parent element and it will catch every event triggered by its children.

document.querySelector('#container').onclick = function(ev) {
  if(ev.target.value) {
    console.log(ev.target.checked, ev.target.value);
  }
}
<div id="container">
  <input type="checkbox" value="Bike">I have a bike<br>
  <input type="checkbox" value="Car">I have a car<br>
  <input type="checkbox" value="Flower">I have a flower<br>
</div>

You don't really need to. Just check the event.target to see if a checkbox was clicked.

var myFunction = function(event) {
    if (event.target.type === "checkbox") {
      var attribute = this.getAttribute("data-myattribute");
      alert(attribute);  
    }
};

Also, there's shorter syntax available for getting data attribute values.

var attribute = this.dataset.myattribute;

You also probably want a change event rather than a click event.

You can use document.querySelectorAll This document.querySelectorAll(".classname input[type='checkbox']"); will select the parent element by it's class and then the child inputs

var classname = document.querySelectorAll(".classname input[type='checkbox']");
classname.forEach(function(item) {
  item.addEventListener('click', function() {
    var attribute = this.getAttribute("data-myattribute");
    console.log(attribute);

  })
})
<div class="classname">
  <input type="checkbox" data-myattribute="1">
  <input type="checkbox" data-myattribute="2">
  <input type="checkbox" data-myattribute="3">
  <input type="checkbox" data-myattribute="4">

</div>

Related