How can I trigger an onchange event manually? [duplicate]
Asked Answered
R

2

596

I'm setting a date-time textfield value via a calendar widget. Obviously, the calendar widget does something like this :

document.getElementById('datetimetext').value = date_value;

What I want is:
On changing value in the date-time textfield I need to reset some other fields in the page. I've added a onchange event listener to the datetimetext field which is not getting triggered, because I guess onchange gets triggered only when the element gets focus & its value is changed on losing focus.

Hence I'm looking for a way to manually trigger this onchange event (which I guess should take care of checking the value difference in the text field).

Any ideas?

Revelation answered 18/5, 2010 at 10:54 Comment(3)
$(document.activeElement).trigger("change");Mandelbaum
$(<ELEMENT_SELECTOR>).change();Batho
the second requires jqueryMcclure
L
586

There's a couple of ways you can do this. If the onchange listener is a function set via the element.onchange property and you're not bothered about the event object or bubbling/propagation, the easiest method is to just call that function:

element.onchange();

If you need it to simulate the real event in full, or if you set the event via the HTML attribute or addEventListener/attachEvent, you need to do a bit of feature detection to correctly fire the event:

if ("createEvent" in document) {
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent("change", false, true);
    element.dispatchEvent(evt);
}
else
    element.fireEvent("onchange");
Liquorice answered 18/5, 2010 at 11:7 Comment(13)
thanks. this works, but am not sure about browser detection here. wondering if there is a way to do the same via YUI library. thanks anyways.Revelation
Thanks. Seems to be working in Android's WebView with those 3 lines from else block.Electioneer
Andy E, this does not work in IE10, any ideas?Borowski
@NickBinnet: interesting. I'm working in Linux at the moment and can't switch to test for a solution, but I would suggest swapping the if and else blocks, and testing for if ('createEvent' in document) instead. Let me know if this works and I'll update the answer.Liquorice
Andy, you are absolutely correct. It works. Could you please add a reference to this answer on the following question. #17755472Borowski
I have a onchange event into a HTML element and element.onchange(); workedChrysanthemum
This will also work - $("#element").trigger('change'); // make sure you define onchange function above this callGerrald
I only see onchange() not work when using addEvent/attachEvent jsfiddle.net/mplungjan/s11uakx7Danziger
its working great, but too damn slow, why is it? Can anything be done to boost performance of app?Remains
this worked for me for an event defined in jQueryJugular
@AndyE Event.initEvent() is deprecated. MDN It is recomended to use the Event() constructor instead.Glazing
This is "The old-fashioned way". Now there is another way. See Milan answer.Potent
"element.onchange is not a function" in latest chromeBushwhacker
D
654

MDN suggests that there's a much cleaner way of doing this in modern browsers:

// Assuming we're listening for e.g. a 'change' event on `element`

// Create a new 'change' event
var event = new Event('change');

// Dispatch it.
element.dispatchEvent(event);
Disingenuous answered 12/5, 2014 at 15:1 Comment(19)
This did not work for me. Are you sure that is not for custom events only?Tecu
@BrettZamir Worked for me (at least in Chrome 36) the following way: document.querySelector('select.freight').dispatchEvent(new Event('change', { 'bubbles': true }))Takeoff
Just FYI on this... MDN does mention this, but its not supported by IE10+ (arguably also modern by definition of the word modern..) and only in the nightly of Safari (as time of writing) IE10+ does have this constructor method but you need to specify the type of event, eg. MouseEvent or KeyboardEvent :see:- msdn.microsoft.com/en-us/library/ie/dn905219%28v=vs.85%29.aspxAcuity
@MrJustastic A year later, MDN lists compatibility with MS Edge (the current version of IE, if you ask Microsoft) and Safari 6. On mobile, it lists iOS Safari 6, and I assume Chrome on Android ought to support it too.Disingenuous
This does not work on IE11Pru
its working great, but too damn slow, why is it? Can anything be done to boost performance of app?Remains
@Remains what is slow? Is it the method of dispatching itself or the handler code attached to the event?Disingenuous
@MilanIliev : I think the method of dispatching itself, because the handler code attached to the event executes fast when I use jquery's trigger() method. I dont want to use jquery since most part of my app is written in javascript. What can I do to improve the performance?Remains
@Remains Not sure why this dispatch method would be slower. Can you provide examples of how you're attaching it in both cases (raw JS and jQuery) and also details on what browser(s) is it slow, and how slow?Disingenuous
@BrettZamir what does the 'bubbles' : true bit do?Maritime
@Rick : When an event "bubbles" in the DOM (like many built-in events), it means that unless a handler attached to the elements in the bubble chain (starting with the element on which an event is dispatched) stops propagation (as via a call to event.stopPropagation()), that element's parent will also be checked for event handlers to fire, with the process repeated until either propagation is stopped or there are no more ancestors (when one is at root). You can get this propagating behavior for events by adding bubbles: true.Tecu
Stopping propagation is different from preventDefault btw which stops default behaviors associated with an element from occurring, such as links being followed or forms being submitted, but it does not stop events being triggered on ancestors.Tecu
element.dispatchEvent(new window.Event('change', { bubbles: true })) if you want to bubble tooRedpencil
While using Chrome 80 in February 2020, the expression document.createEvent('change') gives me a runtime exception: "The provided event type ('change') is invalid.".Berey
It's new CustomEvent('change') now(June 2020/Covid-19).Dilley
@MikeMestnik Actually the above code (.dispatchEvent(new Event('change'))) works just fine for me in FF.Mixologist
Seriously, it's not as convenient as the .click() event? facepalm Trying to determine if dispatchEvent actually supports IE 10+ because it's important to be fully compatible.Kelle
new Event('change') is still valid according to MDN. It just doesn't allow for extra data to be sent?Subroutine
@MikeMestnik , the prototype inheritance and property descriptors are different. May I ask, why not use "Event" but "CustomEvent" exactly? Related: https://mcmap.net/q/65663/-event-vs-customevent (Event vs CustomEvent...) ; w3.org/TR/uieventsWeakling
L
586

There's a couple of ways you can do this. If the onchange listener is a function set via the element.onchange property and you're not bothered about the event object or bubbling/propagation, the easiest method is to just call that function:

element.onchange();

If you need it to simulate the real event in full, or if you set the event via the HTML attribute or addEventListener/attachEvent, you need to do a bit of feature detection to correctly fire the event:

if ("createEvent" in document) {
    var evt = document.createEvent("HTMLEvents");
    evt.initEvent("change", false, true);
    element.dispatchEvent(evt);
}
else
    element.fireEvent("onchange");
Liquorice answered 18/5, 2010 at 11:7 Comment(13)
thanks. this works, but am not sure about browser detection here. wondering if there is a way to do the same via YUI library. thanks anyways.Revelation
Thanks. Seems to be working in Android's WebView with those 3 lines from else block.Electioneer
Andy E, this does not work in IE10, any ideas?Borowski
@NickBinnet: interesting. I'm working in Linux at the moment and can't switch to test for a solution, but I would suggest swapping the if and else blocks, and testing for if ('createEvent' in document) instead. Let me know if this works and I'll update the answer.Liquorice
Andy, you are absolutely correct. It works. Could you please add a reference to this answer on the following question. #17755472Borowski
I have a onchange event into a HTML element and element.onchange(); workedChrysanthemum
This will also work - $("#element").trigger('change'); // make sure you define onchange function above this callGerrald
I only see onchange() not work when using addEvent/attachEvent jsfiddle.net/mplungjan/s11uakx7Danziger
its working great, but too damn slow, why is it? Can anything be done to boost performance of app?Remains
this worked for me for an event defined in jQueryJugular
@AndyE Event.initEvent() is deprecated. MDN It is recomended to use the Event() constructor instead.Glazing
This is "The old-fashioned way". Now there is another way. See Milan answer.Potent
"element.onchange is not a function" in latest chromeBushwhacker

© 2022 - 2024 — McMap. All rights reserved.