How do I programmatically force an onchange event on an input?
JavascriptJavascript Problem Overview
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.
Javascript Solutions
Solution 1 - Javascript
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:
Solution 2 - Javascript
In jQuery I mostly use:
$("#element").trigger("change");
Solution 3 - Javascript
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
Solution 4 - Javascript
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.
Solution 5 - Javascript
Taken from the bottom of http://dev.jquery.com/view/trunk/qunit/testrunner.js">QUnit</a>
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.
Solution 6 - Javascript
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);
Solution 7 - Javascript
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>
Solution 8 - Javascript
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.
Solution 9 - Javascript
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");
Solution 10 - Javascript
For triggering any event in Javascript.
document.getElementById("yourid").addEventListener("change", function({
//your code here
})