Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solution for on change doesn't work when input is changed programmatically [duplicate]

I have already read Why onchange doesn't work? and now I know that,

The onchange event only fires if the user changes the value of the input. It isn't supposed to fire if the input is changed programmatically.

But I have an input field which is automatically filled when user change a location by Google map widget inside a website. When it happens, I want to get that automatically filled value and fill another input filed. How can I detect or fire function when input is changed programmatically?

like image 887
I am the Most Stupid Person Avatar asked Oct 18 '19 11:10

I am the Most Stupid Person


Video Answer


2 Answers

You could achieve this by overriding the setter function of the input's value property. So every time anyone sets the value programmatically your overriden setter will be triggered:

const input = document.getElementById('input');

const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(input), 'value');

Object.defineProperty(input, 'value', {
    set: function(t) {
        console.log('Input value was changed programmatically');
        return descriptor.set.apply(this, arguments);
    },
    get: function() {
      return descriptor.get.apply(this);
    }
});

function changeInput() {
  input.value += '1';
}
<input id="input">
<button onclick="changeInput()">Change</button>
like image 78
Kirill Simonov Avatar answered Oct 17 '22 20:10

Kirill Simonov


To trigger an event programmatically, you can use the Event API : https://developer.mozilla.org/fr/docs/Web/API/EventTarget/dispatchEvent

Full example :

let input = document.getElementById('a')

// Listen the event
input.addEventListener('change', function (evt) {
   console.log('onchange event listener')
});

input.onchange = () => {
console.log('onchange callback')
}

setTimeout(() => {
input.value = "myvalue"

// Trigger the event
var event = new Event('change');
input.dispatchEvent(event);

}, 1000)
<input id="a">
like image 45
Alex83690 Avatar answered Oct 11 '22 19:10

Alex83690