Hassan Imam
Hassan Imam

Reputation: 22574

Pass this to addEventListener() as parameter

I want to add change event to a group of checkboxes, how can I access this in my event function, so that when I do the event I can access value of the checkbox.

This is my current code:

var checkboxes = document.getElementsByClassName('cb');
Array.from(checkboxes).forEach(function(){
  this.addEventListener("change", cbChange(this), false);
});

function cbChange(ele){
  console.log(ele.value);
}
<input class="cb" type="checkbox" name="candidate" value="1"/>
<input class="cb" type="checkbox" name="candidate" value="2"/>
<input class="cb" type="checkbox" name="candidate" value="3"/>
<input class="cb" type="checkbox" name="candidate" value="4"/>

Upvotes: 8

Views: 16667

Answers (5)

From my opinion, i thinks you can use for..of loop to get the value of each checkbox.

var checkboxes = document.getElementsByClassName('cb');
for (let checkboxe of checkboxes ) {
  checkboxe.addEventListener('change', () => {
      console.log(checkboxe.value)
  })
}

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 817238

Inside the forEach callback, this does not refer to a DOM element. It doesn't refer to any useful value.

Secondly, you are immediately calling cbChange and pass its return value to addEventListener, which is undefined. But addEventListener expects to be passed a function, so you either have to pass cbChange or a function that calls cbChange.

Lastly, while you could define the event handler to accept the element as first argument, it's much simpler if it accepts the event object, because that is the default API.

Having said all that, the simplest solution would be:

var checkboxes = document.getElementsByClassName('cb');
Array.from(checkboxes).forEach(function(element){
//                                      ^^^^^^^
  element.addEventListener("change", cbChange, false);
//^^^^^^^  
});

function cbChange(){
  console.log(this.value);
//            ^^^^
}

Since inside an event handler, this refers to the element the handler is bound to, using this inside cbChange just works.


And here are some alternatives:

// Use the event object
var checkboxes = document.getElementsByClassName('cb');
Array.from(checkboxes).forEach(function(element){
  element.addEventListener("change", cbChange, false);
});

function cbChange(event){
  console.log(event.target.value);
}


// Using a wrapper that calls `cbChange`
var checkboxes = document.getElementsByClassName('cb');
Array.from(checkboxes).forEach(function(element){
  element.addEventListener("change", function() { cbChange(this); }, false);
});

function cbChange(ele){
  console.log(ele.value);
}

Upvotes: 11

Dij
Dij

Reputation: 9808

you don't need to pass this to event handler. you can access event.target inside event handler. you can do something like this:

var checkboxes = document.getElementsByClassName('cb');
Array.from(checkboxes).forEach(function(){
  this.addEventListener("change", cbChange, false);
})

function cbChange(event){
  var ele = event.target;
  console.log(ele.value);
}
<input class="cb" type="checkbox" name="candidate" value="1"/>
<input class="cb" type="checkbox" name="candidate" value="2"/>
<input class="cb" type="checkbox" name="candidate" value="3"/>
<input class="cb" type="checkbox" name="candidate" value="4"/>

Upvotes: 2

Nicola Bertelloni
Nicola Bertelloni

Reputation: 333

I think you should use map

const checkboxes = document.getElementsByClassName('cb');
const cbArr = Array.from(checkboxes)
cbArr.map((d) => {
  d.addEventListener("change", cbChange(d), false);
});

function cbChange(ele){
  console.log(ele.value);
}
<input class="cb" type="checkbox" name="candidate" value="1"/>
<input class="cb" type="checkbox" name="candidate" value="2"/>
<input class="cb" type="checkbox" name="candidate" value="3"/>
<input class="cb" type="checkbox" name="candidate" value="4"/>

Upvotes: -1

brk
brk

Reputation: 50346

Remove (this) from cbChange(this). This will immediately execute the function.

To get the value you need the target.target is the element on which event is executed.On consoling ele you will see all available options

var checkboxes = document.getElementsByClassName('cb');
Array.from(checkboxes).forEach(function() {
  this.addEventListener("change", cbChange, false);
});

function cbChange(ele) {
  console.log(ele.target.value);
}
<input class="cb" type="checkbox" name="candidate" value="1" />
<input class="cb" type="checkbox" name="candidate" value="2" />
<input class="cb" type="checkbox" name="candidate" value="3" />
<input class="cb" type="checkbox" name="candidate" value="4" />

Upvotes: 2

Related Questions