1

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

nem035
  • 34,790
  • 6
  • 87
  • 99
Her Man
  • 39
  • 7
  • add `debugger` (just like that, in a new line just after you open the function) to your toggle() function, and inspect what `element, select1, select2` values are. With the chrome console opened, when that function executes, you app will stop on that point, and you should be able to inspect the variables. – JorgeObregon Nov 04 '16 at 15:20
  • What syntax is `elems.1`? – nem035 Nov 04 '16 at 15:26
  • elems is an object which stores all DOM objects used in the code – Her Man Nov 04 '16 at 15:32
  • `elems.1` is not valid JS syntax. Did you mean `elems["1"]` or `elems[1]`? – nem035 Nov 04 '16 at 15:35
  • This is the syntax for elems `var elems = { sel1: document.getElementById("sel1") }` – Her Man Nov 04 '16 at 16:04

1 Answers1

0

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);
    }
  }
}
nem035
  • 34,790
  • 6
  • 87
  • 99
  • Does it matter which function i return and should this function do something? – Her Man Nov 04 '16 at 15:35
  • *"Does it matter which function I return"* - well that depends on your situation, whatever function you return will be passed as the handler part of `addEventListener` and so `addEventListener` will call it when the `change` event happens and override `this` as the element on which the `change` happened as well as pass the `event` object as the first argument. If you need any of those then yes it might matter but for your case it doesn't seem relevant. – nem035 Nov 04 '16 at 15:39
  • *"...and should this function do something"* Well of course it should, it's your event handler. Function `toggle` is just a wrapper function around the function you return, which is the actual handler passed into `addEventListener` and will be called on `change` – nem035 Nov 04 '16 at 15:40
  • See my edit for the more real version of my code syntax.. elems is declared like an object for example: `var elems = { sel1: document.getElementById("sel1")}` – Her Man Nov 04 '16 at 16:08
  • the toggleVisibility function is already doing the handling..: `function toggleVisibility(selector, hide){ var showStyle = hide ? "none" : ""; selector.style.display = showStyle; }` – Her Man Nov 04 '16 at 16:10
  • did you try out the solution I proposed? I suggest you should to read more about [functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions) in JavaScript being [first-class](http://stackoverflow.com/questions/705173/what-is-meant-by-first-class-object), and what [closures](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) are. – nem035 Nov 04 '16 at 16:13
  • Your " return function()" was added, and everything works like a charm! – Her Man Nov 04 '16 at 16:30