182

How do I programmatically force an onchange event on an input?

I've tried something like this:

var code = ele.getAttribute('onchange');
eval(code);

But my end goal is to fire any listener functions, and that doesn't seem to work. Neither does just updating the 'value' attribute.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Soldarnal
  • 7,558
  • 9
  • 47
  • 65

11 Answers11

260

Create an Event object and pass it to the dispatchEvent method of the element:

var element = document.getElementById('just_an_example');
var event = new Event('change');
element.dispatchEvent(event);

This will trigger event listeners regardless of whether they were registered by calling the addEventListener method or by setting the onchange property of the element.


By default, events created and dispatched like this don't propagate (bubble) up the DOM tree like events normally do.

If you want the event to bubble, you need to pass a second argument to the Event constructor:

var event = new Event('change', { bubbles: true });

Information about browser compability:

Miscreant
  • 6,626
  • 3
  • 22
  • 21
  • 3
    Yes, the [MDN Creating and triggering events](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events) is a good resource! – Jakub Holý Jun 17 '16 at 08:56
  • 2
    This is how to do it properly, natively. Supported in all browsers now: http://caniuse.com/#feat=dispatchevent – Willem Mulder Aug 25 '16 at 10:38
  • 1
    This is a **true** answer for this question. We must achieve this in a modern way. – Константин Ван Nov 19 '16 at 09:46
  • 1
    Im trying to do the equivalent on IE11 but it's not working when trying to change a reactjs input field. `var evt = document.createEvent('CustomEvent'); evt.initCustomEvent('input', true, false, { }); elem.dispatchEvent(evt);` – Bodosko May 10 '17 at 16:39
  • 3
    Why is everyone saying this is the best answer? According to the linked Event doc, even the current version of IE *still* doesn't support this. – jeff-h Jun 24 '17 at 03:16
  • How can i pass parameters to the change event ? – delphirules Feb 17 '19 at 13:43
  • 1
    `{ bubbles: true }` this was the fix for my issue. Thanks –  Sep 27 '19 at 12:50
106

In jQuery I mostly use:

$("#element").trigger("change");
Danita
  • 2,464
  • 4
  • 23
  • 29
  • 2
    tihs helped me! I was setting the value of a checkbox (checked or not) using code and the event was not firing in IE at all no matter what i did. I tried blur() focus() and a few other things. after i set the value i called trigger and i added a click event to call trigger as well. It causes multiple fires but it doesnt matter to me. In IE I add checkboxes through code and you have to click on them twice before the change event fires. Thanks for this tip. – Dustin Davis Jul 30 '10 at 21:32
  • 7
    As an update, $("#element").change(); does the same thing since jquery 1.0. – CookieOfFortune Jul 23 '14 at 19:13
  • 5
    Note that this does NOT trigger a native onchange. It will only fire on all the onchange listeners that were bound through jQuery! – Willem Mulder Aug 25 '16 at 10:39
65

ugh don't use eval for anything. Well, there are certain things, but they're extremely rare. Rather, you would do this:

document.getElementById("test").onchange()

Look here for more options: http://jehiah.cz/archive/firing-javascript-events-properly

Kolten
  • 3,495
  • 5
  • 42
  • 59
  • 3
    eval for objectifying JSON ;) – Aaron Powell Sep 25 '08 at 22:39
  • Agreed about eval - I pulled that code from http://stackoverflow.com/questions/33860/is-it-possible-to-call-javascripts-onsubmit-event-programatically-on-a-form as an example of something I don't want. – Soldarnal Sep 25 '08 at 23:00
  • This doesn't appear to work in IE7. Exception of "object doesn't support this property or method" - do you see that too? – theJerm Nov 29 '10 at 20:41
  • 3
    json2.js for objectifying JSON! JSON.parse is already available on modern browsers – jinglesthula Nov 09 '12 at 23:01
  • eval for objectifying JSON is a really bad idea, and can lead to serious security vulnerabilities. ALWAYS use JSON.parse for that sort of thing. – Johntron Feb 25 '14 at 20:41
  • 16
    This technique *only* works if the change handler was attached by setting "onchange". It does not generate a 'real' event that triggers w3c or microsoft event handlers. See the link for more details. – Stephen Nelson Jun 25 '14 at 23:25
  • 6
    I think this answer is outdated now, [Miscreant's answer](http://stackoverflow.com/a/36648958/204205) using `new Event(...)` and `dispatchEvent` is the right solution nowadays, it seems. – Jakub Holý Jun 17 '16 at 08:57
  • This is not how it should be done because it will NOT trigger a general, native, onchange event. Please use the dispatchEvent(new Event('change')) function. See https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events it is supported in all browsers these days. – Willem Mulder Aug 25 '16 at 10:41
  • 1
    Not working... use instead jQuery: `$("#element").trigger("change");` OR javaScript: `var event = new Event('change'); element.dispatchEvent(event);` – Amit Shah Oct 13 '16 at 07:38
  • 1
    @AmitShah jQuery $('#element').trigger('change'); worked perfectly for me. Thank you. – Alexander Dixon Nov 16 '16 at 16:59
  • 7
    **This answer is obsoleted**; the code above will not work if you used `Element.addEventListener` to handle events. To achieve it in a modern way, see @Miscreant's answer. – Константин Ван Nov 19 '16 at 09:52
24

For some reason ele.onchange() is throwing a "method not found" expception for me in IE on my page, so I ended up using this function from the link Kolten provided and calling fireEvent(ele, 'change'), which worked:

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);
    }
}

I did however, create a test page that confirmed calling should onchange() work:

<input id="test1" name="test1" value="Hello" onchange="alert(this.value);"/>
<input type="button" onclick="document.getElementById('test1').onchange();" value="Say Hello"/>

Edit: The reason ele.onchange() didn't work was because I hadn't actually declared anything for the onchange event. But the fireEvent still works.

Community
  • 1
  • 1
Soldarnal
  • 7,558
  • 9
  • 47
  • 65
  • 2
    I like this method of browser detection (by object detection) better than the example I provided. – Chris MacDonald Sep 25 '08 at 23:22
  • This do not work anymore for Firefox 23 : "element.dispatchEvent is not a function" – Oliver Sep 04 '13 at 22:15
  • 5
    Hi fellow Googlers. It's 2016! Nowadays we write code like `element.dispatchEvent(new Event('change', true, true))` instead of all that arcane and mostly deprecated `createEvent` and `initEvent` stuff. – ericsoco May 28 '16 at 06:06
3

This is the most correct answer for IE and Chrome::

var element = document.getElementById('xxxx');
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', false, true);
element.dispatchEvent(evt);
Oli
  • 9,766
  • 5
  • 25
  • 46
Peter Lo
  • 55
  • 6
2

Taken from the bottom of QUnit

function triggerEvent( elem, type, event ) {
    if ( $.browser.mozilla || $.browser.opera ) {
        event = document.createEvent("MouseEvents");
        event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
            0, 0, 0, 0, 0, false, false, false, false, 0, null);
        elem.dispatchEvent( event );
    } else if ( $.browser.msie ) {
        elem.fireEvent("on"+type);
    }
}

You can, of course, replace the $.browser stuff to your own browser detection methods to make it jQuery independent.

To use this function:

var event;
triggerEvent(ele, "change", event);

This will basically fire the real DOM event as if something had actually changed.

Chris MacDonald
  • 5,975
  • 4
  • 34
  • 35
1

If you add all your events with this snippet of code:

//put this somewhere in your JavaScript:
HTMLElement.prototype.addEvent = function(event, callback){
  if(!this.events)this.events = {};
  if(!this.events[event]){
    this.events[event] = [];
    var element = this;
    this['on'+event] = function(e){
      var events = element.events[event];
      for(var i=0;i<events.length;i++){
        events[i](e||event);
      }
    }
  }
  this.events[event].push(callback);
}
//use like this:
element.addEvent('change', function(e){...});

then you can just use element.on<EVENTNAME>() where <EVENTNAME> is the name of your event, and that will call all events with <EVENTNAME>

Wntiv Senyh
  • 39
  • 1
  • 4
0

The change event in an input element is triggered directly only by the user. To trigger the change event programmatically we need to dispatch the change event.

The question is Where and How?

"Where" we want the change event to be triggered exactly at the moment after a bunch of codes is executed, and "How" is in the form of the following syntax:

const myInput = document.getElementById("myInputId");

function myFunc() {
  //some codes
  myInput.dispatchEvent(new Event("change"));
}

In this way, we created the change event programmatically by using the Event constructor and dispatched it by the dispatchEvent() method. So whenever myFunc() method is invoked, after the //some codes are executed, our synthetic change event is immediately triggered on the desired input element.‍

Important result: Here, the change event is triggered by executing the //some codes in myFunc() instead of changing the input value by the user (default mode).

Hamid Heydari
  • 141
  • 2
  • 4
-5

if you're using jQuery you would have:

$('#elementId').change(function() { alert('Do Stuff'); });

or MS AJAX:

$addHandler($get('elementId'), 'change', function(){ alert('Do Stuff'); });

Or in the raw HTML of the element:

<input type="text" onchange="alert('Do Stuff');" id="myElement" />

After re-reading the question I think I miss-read what was to be done. I've never found a way to update a DOM element in a manner which will force a change event, what you're best doing is having a separate event handler method, like this:

$addHandler($get('elementId'), 'change', elementChanged);
function elementChanged(){
  alert('Do Stuff!');
}
function editElement(){
  var el = $get('elementId');
  el.value = 'something new';
  elementChanged();
}

Since you're already writing a JavaScript method which will do the changing it's only 1 additional line to call.

Or, if you are using the Microsoft AJAX framework you can access all the event handlers via:

$get('elementId')._events

It'd allow you to do some reflection-style workings to find the right event handler(s) to fire.

Aaron Powell
  • 24,927
  • 18
  • 98
  • 150
  • 1
    I believe he wants to fire the actual event, not run a function when the event is fired... i _think_. lol – Kolten Sep 25 '08 at 22:49
-7

Using JQuery you can do the following:

// for the element which uses ID
$("#id").trigger("change");

// for the element which uses class name
$(".class_name").trigger("change");
Community
  • 1
  • 1
-7

For triggering any event in Javascript.

 document.getElementById("yourid").addEventListener("change", function({
    //your code here
})
Hareesh Seela
  • 37
  • 1
  • 2