0

I have a form on a page with multiple inputs. I want to handle events if someone put anything to my form by code in browser console(or browser extension or browser automation tools like puppeteer).

e.g. Code that changes value in a form and I want to be able to get some event when value of my input element is changed.

let element = document.querySelector('#test');
element.value = 'x';

I expect that this code should cause some event/mutation that I can handle. But nothing is triggered. I haven't find any event that is triggered and mutation on attribute change also doesn't work.

The strange thing is that when input value is changed by element.value = 'x', mutation is not triggered. But when setAttribute is used everything works fine element.setAttribute('value', 'x')

My code:

const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation) {
      console.log('Mutation happened');
      let observer = document.querySelector('#observer');
      observer.value = 'Mutation happened';
    }
  });
});

let element = document.querySelector('#test');

observer.observe(element, { attributes: true });

//Setting value by using setAttribute API causes mutation
//element.setAttribute('value', 'a');

//Setting value by using `.value` API does not cause mutation
element.value = 'b';
Input field: <input id='test' onInput='console.log(1)'/><br/>
Does mutation happen? <input id='observer' value='Mutation did not happen'/>

How to catch changing of value of HTML input by Javascript code? It should not be necessary MutationObserver. Any option will be fine.

Anton
  • 9,682
  • 11
  • 38
  • 68
  • Whatever changes the value needs to manually trigger the appropriate event after a change. `element.dispatchEvent(new Event('input'));` Then you can catch the change with event listeners. – Emiel Zuurbier Mar 14 '23 at 22:50
  • The MutationObserver works as expected. It registers changes in the HTML, like with `setAttribute`. But changing the `value` property doesn't change anything in the HTML. – Emiel Zuurbier Mar 14 '23 at 22:52
  • @EmielZuurbier The problem is that I don't control change of input by code. I can't ask bot creator to add dispatching of events... – Anton Mar 14 '23 at 22:53
  • Unfortunately there is no way around. If you programmatically change the value of an input, then you need to manually fire an event to trigger the event listener. – Emiel Zuurbier Mar 14 '23 at 22:59
  • @EmielZuurbier then it look like a gap in specification. You can change value in `input` element using `value` property, but you can't trigger anything on this change. – Anton Mar 14 '23 at 23:09
  • You don't always *want* to trigger an event when changing a `value` property, so it makes sense they designed it this way. – Emiel Zuurbier Mar 14 '23 at 23:31
  • This is not a gap in the specification. The meaning of `value` attribute is to specify the initial value not to reflect the current value: [link](https://html.spec.whatwg.org/multipage/input.html#the-input-element:~:text=The%20value%20content%20attribute%20gives%20the%20default). – wOxxOm Mar 14 '23 at 23:32
  • 1/2 - Basically the choice was 1. Handle the rare case where an author changes the value by code and wants someone else's code to handle that value change (i.e fire an event when `.value` is set), 2. Handle the more common case of changing the value in response to the user change and edit the value, without triggering an event they don't want to handle (because they triggered it). – Kaiido Mar 15 '23 at 03:26
  • 2/2 - Think of something like `onchange = (evt) => { inp.value = format(inp.value); };`. In the best case `format(format(value))` produces the same as a single call, and we just wasted some computation, but if it doesn't (e.g percent-encoding), then you have an infinite loop. Also, even if you somehow setup something to handle that, if there is another listener, it will also be called twice, with the first time handling the new event even before your handler returned, and the second time handling the first, "trusted", event, because the event would have to be fired synchronously. – Kaiido Mar 15 '23 at 03:26
  • @Kaiido 1) I don't control that execution 2) onchange is not triggered, it doesn't change anything – Anton Mar 15 '23 at 08:55
  • 1. Yes, you're in the "rare" case of having code running on your page that you don't control. 2. The fact the attribute represents the "intial value" and that the change event isn't fired on script setting both come from the same design decisions. + more specific to the attribute, what should be the attribute value when the user is typing? What about composed characters like in CJK? – Kaiido Mar 15 '23 at 10:56

0 Answers0