Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onchange event and programmatic input value change conflict on IE

I've noticed that in different versions of Internet Explorer the onchange event is not captured when the value of an input is altered by a js function, behavior that does not occur with other browsers such as Mozilla or Chrome.

Investigating a little I found that the correct operation of onchange in IE is not guaranteed when the value is altered by js:

  • onchange not fired on IE
  • onchange not fired when autocomplete is on

    Example (test on IE):

function onchangeRequest(){
  console.log('onchange fired');
}

function changeValue (input){
  input.value +=  "hello"
}
<h4> focus lost doesnt invoke onchangeRequest() </h4>

<input id="valueInput"  onkeyup="changeValue(this);" onchange="onchangeRequest();" />

<h4> focus lost invokes onchangeRequest() </h4>

<input id="valueInput" onchange="onchangeRequest();" />

I have not found a convincing explanation of the reasons why IE does not solve those situations correctly. Is this a "known bug" which we have to deal with? Is there any official reference where it is stated that IE does not guarantee the correct behavior of onchange event?

like image 824
Marcos Martínez Avatar asked Jul 05 '17 00:07

Marcos Martínez


1 Answers

I have found that for many years Microsoft followed a strategy whereby it didnt follow the W3C standards in its browser, but the behavior is correct according to IE's own specification:

The onchange event does not fire when the selected option of the select object is changed programmatically.

Reference: MSDN - onchange event

A possible workaround to solve this problem and make your solution cross browser would be:

  • onfocus: save the input value on a expando property
  • onblur: call a js function that compares the old value with the current value.

In my real life scenario i need to fire an ajax action just when the input value changed, so using onblur event without comparing changes would result in a lot of unnecessary calls to the backend.

Here is an example:

function onchangeRequest(input){
  if(input.value != input.oldValue){
      console.log('value changed: do ajax request');
  }else{
      console.log('value didnt change');
  }
}

function changeValue (input){
     input.value +=  "add"
 }
<input id="valueInput" onkeyup="changeValue(this);" onfocus="this.oldValue = this.value;" onblur="onchangeRequest(this);" />
like image 161
Marcos Martínez Avatar answered Oct 22 '22 23:10

Marcos Martínez