2

I am trying to change the input text (total INR) of the input field in this page by doing:

$(".cKOnhg").last().attr('value', Math.random() * 100000);

When inspected the "value" attribute of the input changes to a random number, however it automatically changes back to 0 (or the number that was manually inputted) after few seconds.

I have tried trigger() and the sendkeys plugin mentioned here: https://stackoverflow.com/a/13946504/82985

Nothing seems to work. Is it even possible on this page to change the input value exactly like how a human would do?

I'm trying to change the input values and auto-submit the form.

Guerric P
  • 30,447
  • 6
  • 48
  • 86
Yeti
  • 5,628
  • 9
  • 45
  • 71
  • 1) if the code in the question is working, but something else is resetting it's value, then you need to find the line of code causing that reset to happen. It is not a built-in behaviour of JS or jQuery; something in your code is causing it to happen. Unfortunately we can't help with that. As a starting point for your debugging I'd suggest using devtools to inspect what event handlers are bound to the element to see what actions they perform. 2) Not really relevant to the problem, but to update the value of an `input` use `val()`, not `attr()`: https://jsfiddle.net/RoryMcCrossan/78rdbpfv/ – Rory McCrossan Mar 08 '21 at 19:46
  • Also, jQuery is not loaded in the page you've linked to. What library are you using which the `$` refers to? – Rory McCrossan Mar 08 '21 at 19:50
  • Thanks for the tips. I'm injecting jquery using Tampermonkey. – Yeti Mar 08 '21 at 19:52
  • @RoryMcCrossan "I'd suggest using devtools to inspect what event handlers are bound to the element to see what actions they perform" - how do I do this? – Yeti Mar 09 '21 at 06:47
  • If you're using Chrome, right click the element you want to look at in your browser and click 'Inspect'. Then in the right tab of the right pane click 'Event listeners'. Other browsers have the same feature, just the wording may be slightly different – Rory McCrossan Mar 09 '21 at 08:59

1 Answers1

7

This page is using React under the hood. The problem when you try to programmatically set the value is that you only update the DOM, but the underlying React's state remains the same, so the DOM gets reset on the next render tick.

In order to correctly update the input value, use this code (you don't need jQuery at all):

function setNativeValue(element, value) {
  const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
  const prototype = Object.getPrototypeOf(element);
  const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;

  if (valueSetter && valueSetter !== prototypeValueSetter) {
    prototypeValueSetter.call(element, value);
  } else {
    valueSetter.call(element, value);
  }
}

// Wait for the DOM to be fully rendered by React before doing anything
window.addEventListener("load", function() {
    const el = Array.from(document.querySelectorAll('.cKOnhg')).pop();

    setNativeValue(el, Math.random() * 100000);
    el.dispatchEvent(new Event('input', { bubbles: true }));
});

Explanation: in order to trigger a value change in React, you have to bypass the custom value setter that is added by the framework on the HTMLInputElement instance, which overrides the one from HTMLInputElement.prototype (the native one). Once you've done that, emit an input event to notify the framework that the value has changed, for correct taking into account by the framework.

More information about this: https://github.com/facebook/react/issues/10135

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • Thanks for the reply! Just seeing it now.. Will try it tomorrow and let you know how it goes. – Yeti Mar 18 '21 at 19:30
  • I tried it but got this error: `TypeError: Cannot convert undefined or null to object` in this line `const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;` – Yeti Mar 19 '21 at 14:29
  • I've edited my answer to fix your problem – Guerric P Mar 19 '21 at 15:08
  • It's giving the same error: https://ibb.co/0Fdy6RG. Just to make sure the code is placed correctly, I've placed a debug message inside `window.addEventListener` which is printed correctly – Yeti Mar 19 '21 at 15:40
  • I've tested this with Tampermonkey just like you... I don't really get what's happening there. Can you confirm that the code works when you copy it in the console (without the `load` event listener)? – Guerric P Mar 19 '21 at 17:45
  • It worked! Sorry it was my mistake - the error was because of some other code. When I removed all other code it worked. Thanks.. please have the bounty! – Yeti Mar 19 '21 at 18:06
  • 1
    Thanks very much for this. I wish it wasn't so complicated but it really saved me a lot of typing – JZL003 May 04 '22 at 18:13