Soldarnal
Soldarnal

Reputation: 7778

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

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.

Upvotes: 198

Views: 341826

Answers (8)

Hamid Heydari
Hamid Heydari

Reputation: 269

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).

Upvotes: -1

Miscreant
Miscreant

Reputation: 7356

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:

Upvotes: 297

Peter Lo
Peter Lo

Reputation: 85

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

Upvotes: 4

STEEL ITBOY
STEEL ITBOY

Reputation: 1

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

Upvotes: -8

Danita
Danita

Reputation: 2514

In jQuery I mostly use:

$("#element").trigger("change");

Upvotes: 109

Soldarnal
Soldarnal

Reputation: 7778

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.

Upvotes: 24

Chris MacDonald
Chris MacDonald

Reputation: 6126

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.

Upvotes: 2

Kolten
Kolten

Reputation: 3503

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

Upvotes: 65

Related Questions