Change <select>'s option and trigger events with JavaScript

JavascriptHtmlDomHtml SelectDom Events

Javascript Problem Overview


How can I change an HTML <select>'s option with JavaScript (without any libraries like jQuery), while triggering the same events as if a user had made the change?

For example using following code, if I change the option with my mouse then an event triggers (i.e. onchange is run). However, when I change the option using JavaScript then it doesn't fire any event. Is it possible to fire trigger associated event handlers like onclick, onchange, etc., when an option is selected with JavaScript?

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" onclick='document.getElementById("sel").options[1].selected = true;' value="Change option to 2" />

http://jsfiddle.net/xwywvd1a/

Javascript Solutions


Solution 1 - Javascript

Unfortunately, you need to manually fire the change event. And using the Event Constructor will be the best solution.

var select = document.querySelector('#sel'),
    input = document.querySelector('input[type="button"]');
select.addEventListener('change',function(){
    alert('changed');
});
input.addEventListener('click',function(){
    select.value = 2;
    select.dispatchEvent(new Event('change'));
});

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3' selected>Three</option>
</select>
<input type="button" value="Change option to 2" />

And, of course, the Event constructor is not supported in IE. So you may need to polyfill with this:

function Event( event, params ) {
	params = params || { bubbles: false, cancelable: false, detail: undefined };
	var evt = document.createEvent( 'CustomEvent' );
	evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
	return evt;
}

Solution 2 - Javascript

Fiddle of my solution is here. But just in case it expires I will paste the code as well.

HTML:

<select id="sel">
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" id="button" value="Change option to 2" />

JS:

var sel = document.getElementById('sel'),
    button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    
    // firing the event properly according to StackOverflow
    // http://stackoverflow.com/questions/2856513/how-can-i-trigger-an-onchange-event-manually
    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent("change", false, true);
        sel.dispatchEvent(evt);
    }
    else {
        sel.fireEvent("onchange");
    }
});

sel.addEventListener('change', function (e) {
    alert('changed');
});

Solution 3 - Javascript

It is as simple as this:

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    sel.onchange();
});

But this way has a problem. You can't call events just like you would, with normal functions, because there may be more than one function listening for an event, and they can get set in several different ways.

Unfortunately, the 'right way' to fire an event is not so easy because you have to do it differently in Internet Explorer (using document.createEventObject) and Firefox (using document.createEvent("HTMLEvents"))

var sel = document.getElementById('sel');
var button = document.getElementById('button');

button.addEventListener('click', function (e) {
    sel.options[1].selected = true;
    fireEvent(sel,'change');

});


function fireEvent(element,event){
    if (document.createEventObject){
    // dispatch for IE
    var evt = document.createEventObject();
    return element.fireEvent('on'+event,evt)
    }
    else{
    // dispatch for firefox + others
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent(event, true, true ); // event type,bubbling,cancelable
    return !element.dispatchEvent(evt);
    }
}

Solution 4 - Javascript

The whole creating and dispatching events works, but since you are using the onchange attribute, your life can be a little simpler:

http://jsfiddle.net/xwywvd1a/3/

var selEl = document.getElementById("sel");
selEl.options[1].selected = true;
selEl.onchange();

If you use the browser's event API (addEventListener, IE's AttachEvent, etc), then you will need to create and dispatch events as others have pointed out already.

Solution 5 - Javascript

Try this:

<select id="sel">
 <option value='1'>One</option>
  <option value='2'>Two</option> 
  <option value='3'>Three</option> 
  </select> 
  
  
  <input type="button" value="Change option to 2"  onclick="changeOpt()"/>
  
  <script>
  
  function changeOpt(){
  document.getElementById("sel").options[1].selected = true;
  
alert("changed")
  }
  
  </script>

Solution 6 - Javascript

These questions may be relevant to what you're asking for:

Here are my thoughts: You can stack up more than one call in your onclick event like this:

<select id="sel" onchange='alert("changed")'>
  <option value='1'>One</option>
  <option value='2'>Two</option>
  <option value='3'>Three</option>
</select>
<input type="button" onclick='document.getElementById("sel").options[1].selected = true; alert("changed");' value="Change option to 2" />

You could also call a function to do this.

If you really want to call one function and have both behave the same way, I think something like this should work. It doesn't really follow the best practice of "Functions should do one thing and do it well", but it does allow you to call one function to handle both ways of changing the dropdown. Basically I pass (value) on the onchange event and (null, index of option) on the onclick event.

Here is the codepen: http://codepen.io/mmaynar1/pen/ZYJaaj

<select id="sel" onchange='doThisOnChange(this.value)'>
<option value='1'>One</option>
<option value='2'>Two</option>
<option value='3'>Three</option>
</select>
<input type="button" onclick='doThisOnChange(null,1);' value="Change option to 2"/>

<script>
doThisOnChange = function( value, optionIndex)
{
    if ( optionIndex != null )
    {
       var option = document.getElementById( "sel" ).options[optionIndex];
       option.selected = true;
       value = option.value;
    }
    alert( "Do something with the value: " + value );
}
</script>

Solution 7 - Javascript

html using Razor:

 @Html.DropDownList("test1", Model.SelectOptionList, new { id = "test1", onchange = "myFunction()" })

JS Code:

function myFunction() {
            
            var value = document.getElementById('test1').value;

            console.log("it has been changed! to " + value );
        }

Solution 8 - Javascript

You can fire the event manually after changing the selected option on the onclick event doing: document.getElementById("sel").onchange();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1798933View Question on Stackoverflow
Solution 1 - JavascriptLewisView Answer on Stackoverflow
Solution 2 - JavascriptKarolView Answer on Stackoverflow
Solution 3 - JavascriptmyhappycodingView Answer on Stackoverflow
Solution 4 - JavascriptRyan WhealeView Answer on Stackoverflow
Solution 5 - JavascriptVicky GonsalvesView Answer on Stackoverflow
Solution 6 - Javascriptmmaynar1View Answer on Stackoverflow
Solution 7 - JavascriptPrimoshenkoView Answer on Stackoverflow
Solution 8 - JavascripteldanoView Answer on Stackoverflow