Search code examples
javascripthtmljsphtml-selectonchange

Execute some Javascript onChange using options?


I've been lurking a bit and couldn't find the answer. Basically I have a bunch of buttons that I want to turn into a drop down menu and have the code be executed onChange. But, I'm new to javascript and I am having a hard time figuring out how this would work. I somewhat got it to work, but I couldn't get it to work with more than one option. Here's what I have:

<button class="lightbutton" onclick="lightswitch(1,true);lightswitch(2,true);lightswitch(3,true);">
All lights on</button> 
<button class="lightbutton" onclick="lightswitch(1,false);lightswitch(2,false);lightswitch(3,false);">
All lights off</button>

I got the lights to turn on by doing this:

<form name="functions">
<select name="jumpmenu" onChange="lightswitch(1,true);lightswitch(2,true);lightswitch(3,true);">
<option>LightFunctions</option>
<option value="*";>Light 1 On</option>
<option value="*";>Light 1 Off</option>
</select>
</form>

Now, I see why it works -- it's just telling it that whenever it changes to turn on all the lights. But how do I change the "onChange" to make it so it gets whichever option I have chosen?

I think I'm missing some JS but unsure.

I appreciate the help.


Solution

  • To have that select element control just the first lightswitch you can do this:

    <select name="jumpmenu" onChange="lightswitch(1,this.value==='on');">
    <option value="on";>Light 1 On</option>
    <option value="off";>Light 1 Off</option>
    </select>
    

    That is, instead of hardcoding true as the second parameter to lightswitch() test the current value of the select element. (Note that I've changed the value attributes to something more meaningful. The expression this.value==='on' will evaluate to either true or false.)

    Within the select's onChange attribute this will refer to the select element itself.

    EDIT: To have the same select control multiple parameters you can add some data- attributes to the option elements to store as many extra parameters per option as needed (in this case I think you only need one extra). And I'd move the logic out of the inline attribute:

    <select name="jumpmenu" onChange="jumpChange(this);">
      <option value="">LightFunctions</option>
      <option data-switchNo="1" value="on";>Light 1 On</option>
      <option data-switchNo="1" value="off";>Light 1 Off</option>
      <option data-switchNo="2" value="on";>Light 2 On</option>
      <option data-switchNo="2" value="off";>Light 2 Off</option>
      <option data-switchNo="3" value="on";>Light 3 On</option>
      <option data-switchNo="3" value="off";>Light 3 Off</option>
    </select>
    
    function jumpChange(sel) {
       if (sel.value === "") return; // do nothing if user selected first option
    
       var whichLight = +sel.options[sel.selectedIndex].getAttribute("data-switchNo");
       lightswitch(whichLight, sel.value==='on');
    
       sel.value = ""; // reset select to display the "Light Functions" option
    }
    

    Demo: http://jsfiddle.net/N7b8j/2/

    Within the jumpChange(sel) function that I added the parameter sel will be the select element (set as this from the onChange attribute). The "magic" happens on this line:

    var whichLight = +sel.options[sel.selectedIndex].getAttribute("data-switchNo");   
    

    To explain that line: sel.options[sel.selectedIndex] gets a reference to the currently selected option, and .getAttribute("data-switchNo") gets that option's data- attribute. The + converts the attribute from a string to a number.