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

154,060

Solution 1

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

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

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

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 5

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.

Share:
154,060
user1798933
Author by

user1798933

Updated on April 27, 2020

Comments

  • user1798933
    user1798933 about 4 years

    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/

  • Karol
    Karol over 9 years
    This is another fake solution. What if someone attached a lot of handlers to onchange on select element? How will this construction work? The one thing for sure is that it will not trigger any of them...
  • Teemu
    Teemu over 9 years
    This works (with some limitations) only when onchange property has been set, not with inline handlers.
  • Eraden
    Eraden over 9 years
    Additionally: button.addEventListener('click', function (e) { sel.options[1].selected = true; /*since ie9 this is possible, for ie8 and below you need to add some hacks*/ sel.dispatchEvent( new CustomEvent('change') ); });
  • Abid Ali
    Abid Ali about 6 years
    what if i again select the same option. It does not fire the change event again.
  • Hassan Dad Khan
    Hassan Dad Khan over 5 years
    If i run $('#sel').val('3'); it will not get fire. Do you have any idea why?
  • aatwo
    aatwo about 4 years
    was having this issue in react / electron. The last part of this answer was the only fix that worked for me! Thank you.
  • Kieran Ryan
    Kieran Ryan over 3 years
    Thanks Karol "createEvent" path in Angular also works for IE11 :-)
  • gary
    gary about 3 years
    For React developers, you must use new Event('input', { bubbles: true }). the bubbles: true is essential to propagate the event to React's event handling layer.
  • Mithun Billara
    Mithun Billara over 2 years
    document.getElementById(...).onchange is not a function if there is no inline handlers.
  • Kamran
    Kamran about 2 years
    The alert is a blocking function. Instead try using console.log.