Onchange event will not fire


<html>
<head>
<script type="application/ecmascript">
function raise(){document.getElementById("btcount").value=document.getElementById("btcount").value*1+1;}
function update(){document.getElementById("result").innerHTML=document.getElementById("btcount").value;}
function init(){document.getElementById("bt").addEventListener("click", raise, false);    document.getElementById("btcount").addEventListener("change", update, false);}
addEventListener("load", init, false);
</script>
</head>
<body>
<input id="bt" type="button" value="test" /><input type="text" id="btcount" value="0" /><p id="result"></p>
</body>
</html>

Why does the change event not fire?

It works for me.

When I click on the “test” button, the value in the text input increments.

When I change the value of the text input, the value appears below it.

I’m guessing you want the raise function to trigger a change event?

Exactly, the raise function changes the value of the text-input, so I would expect the chang event to be triggered.

I guess you could have raise() call update() or have it explicitly fire a change event. As for understanding the “why not?”, maybe its a “bubble up” vs. “bubble down” thing?

certainly not a bubble up/down thing; and I am currently solving it by calling update.
The reason it does not work is indeed my main intrest.

The reason that the change event doesn’t fire on a scripted update to the field, is that the change event only automatically fires on user interaction.

By definition from: http://www.w3.org/TR/html4/interact/scripts.html

The onchange event occurs when a control loses the input focus and its value has been modified since gaining focus.

I believe that some web browsers used to trigger the onchange event when a script made a change to an element, but if that onchange triggered another change to the same element, endless loops were easy to get in to, and hard to get out of.

If you instead use the standard event declarations for the elements:


document.getElementById("bt").onclick = raise;
document.getElementById("btcount").onchange = update;

you can then trigger the onchange event once your update has been made:


function raise() {
    var btcount = document.getElementById("btcount");
    btcount.value = btcount.value * 1 + 1;
    btcount.onchange();
}

Thanks for the explanation Paul.
I’m going for the eventlistener approach thouhg, so I can have multiple functions triggered by one event if necessary.

That’s the problem with using the eventlistener technique. Web browsers don’t have as much access to it as they do with the standard event techniques, so you’ll need to double-up on the calls to the update function while you continue to use eventlistener.

The best solution for me, would be for the W3C to review their change event definition;-)