Her Man Her Man - 1 month ago 9
Javascript Question

Combined couple toggle functions into one, toggle doesn't function anymore

I've combined a couple functions into one function.
The old functions were made to hide two select blocks when another select block was selected.

It looked something like this:

function toggle1 (){
if (getValue(elems.sel1) !== 0) { // <-- This function is getting the values of the selectfields
toggleVisibility(elems.sel2, true); // <-- This function is defining wether to hide or to show this selectfield
toggleVisibility(elems.sel3, true);
} else {
toggleVisibility(elems.sel2, false);
toggleVisibility(elems.sel3, false);
}
}


The function calling looked like this:

elems.sel1.addEventListener("change", toggle1);


I changed the function into this:

function toggle(element, select1, select2) {
if (getValue(element) !== 0) {
toggleVisibility(select1, true);
toggleVisibility(select2, true);
} else {
toggleVisibility(select1, false);
toggleVisibility(select2, false);
}
}


Calling this function looks now like:

elems.sel1.addEventListener("change", toggle(elems.sel1, elems.sel2, elems.sel3));


Looks very nice and all.. giving me no errors or what so ever.. BUT, the toggle doesn't toggle! Can maybe someone tell me what i'm doing wrong here?

If needed: You can find the complete code at JS FIDDLE

Answer

The reason toggle1 is working is because you're passing it as a function reference into addEventListener.

 // toggle1 is passed as a reference to a function
 // notice no () after it
 elems.sel1.addEventListener("change", toggle1) 

The reason toggle isn't working is because you're calling it first and then passing whatever it returns (which is undefined) into addEventListener.

// toggle is called first (notice () after toggle)
// then its result is passed as the handler
elems.sel1.addEventListener("change", toggle(elems.sel1, elems.sel2, elems.sel3));

This gets called first toggle(elems.sel1, elems.sel2, elems.sel3) and then the listener is passed as whatever was returned from there:

elems.sel1.addEventListener("change", undefined);

What you can do is make toggle return a handler function and the listener will fire:

function toggle(element, select1, select2) {
  return function() { // <--- return a function
    if (getValue(element) !== 0) {
      toggleVisibility(select1, true); 
      toggleVisibility(select2, true);
    } else {
      toggleVisibility(select1, false);
      toggleVisibility(select2, false);
    }
  }
}